Windows 11 v26080 Csharp First FPS moving the player
Windows 11 v26100 Csharp First FPS moving the player
Who am i / About the author...
since 2001, Insider since 2014.
Thanks to Microsoft EMEA GBS to let me participate in the year 2014 to the Insider project during my work. Then, This Windows test project, here in version 11, is based on the cycle of the insider Preview Builds, now in the Dev Channel: it is fun to test the new features. I can learn new features, validate them and share them with you :-)
Why game engines? Because as a system/network/database developer I only see consoles and screens with unfunny and ugly text. With game engines i can show you colors and animations, that's more fun and more eye-catching :)
This tutorial is made in a test environment, for pleasure and not to earn money. It is a non-profit project. It shows that the concept is possible, for a demontration, artistic, or educational purposes, school learning course. Don't test in a real environment in production.
Windows 11 v26100 Csharp First FPS moving the player : last articles
Windows 11 v23619 testing with a Unity game engine Hello World
How to use signals with Godo Engine (Red bouncing ball)
A Paddle Game with Godot engine
Windows 11 v26058 C Sharp with Copilot Godot Engine multiplayer client server POC
Windows 11 v26080 Blender installation
Windows 11 v26100 Csharp First FPS building the level
Windows 11 v26100 Csharp First FPS creating a health pickup
Windows 11 v26100 Csharp First FPS moving the player : object creation
Goal : have a player (capsule) that can be controlled with keyboard input and a camera to follow the player (capsule) as it moves.
I add a player capsule to the scene :
Hierarchy / +3D/ Capsule
I rename it « Player »
Inspector/Transform : Y=1
Position X=3.6 ; Y=-4 ; Z=-10.7
I select the Player GameObject and click on Add Component at the bottom of the Inspector
tab. I search for Physics/Rigidbody and hit Enter to add it.
Inspector/ Rigidbody/Contraints/ I freeze rotation on x, y and z
Project panel/Material folder/create material/ named : Player_Mat
Inspector : Albedo : pick color : R :0 ; G :255 ; B :0
I drag this new material to the Player object in the Hierarchy panel
The capsule player is now green.
Windows 11 v26100 Csharp First FPS moving the player : new camera
One camera is focused on the arena and i want now another camera focused on the player to see it in action
I create another camera
Sample Scene/ Game Object / Camera
I rename it Camera3
I right click the Scene tab/ add tab: "game"
Inspector / Target display / Display3
I move it to position X=1.5; Z=-20
Now, when i select Display3 in the Game tab, i see what Camera3 see.
Windows 11 v26100 Csharp First FPS moving the player : vectors
Objective : move and rotate a GameObject using its Transform component.
I can use Translate and Rotate methods in the Transform class.
- Vectors
For a GameObject position in 3 dimension, i use a vector3 :
https://docs.unity3d.com/ScriptReference/Vector3.html
I can use this vector to hold a position in the scene :
Vector3 Origin = new Vector(1f, 1f, 1f);
To move forward, we can use the forward method :
Vector3 ForwardDirection = Vector3.forward;
No matter which way the GameObject look, this code will always know which way is forward.
https://docs.unity3d.com/Manual/VectorCookbook.html
Windows 11 v26100 Csharp First FPS moving the player : getting the player input
Edit/Project settings/Input manager
the new Input System at https://unity.com/features/input-system
and a great tutorial at https://learn.unity.com/project/using-the-input-system-in-unity
In the script folder, i create a script called PlayerBehavior
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerBehavior : MonoBehaviour
{
public float MoveSpeed = 10f;
public float RotateSpeed = 75f;
private float _vInput;
private float _hInput;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
_vInput = Input.GetAxis("Vertical") * MoveSpeed;
_hInput = Input.GetAxis("Horizontal") * RotateSpeed;
this.transform.Translate(Vector3.forward * _vInput *
Time.deltaTime);
this.transform.Rotate(Vector3.up * _hInput *
Time.deltaTime);
}
}
I attach this script to the player by dragndropping the script on the Hierarchy/Player GameObject
I test and see the player moving while i presse the up and down keys
Windows 11 v26100 Csharp First FPS moving the player : using quaternion with euler angles
*update*
Instad of moving the gameObject Transform property, its is a better method to move the Rigidbody by adding a force, because in this way, the Rigidbody will interact better in the scene thanks to the physics engine. Read that:
https://docs.unity3d.com/ScriptReference/Rigidbody.AddForce.html
use other Rigidbody class methods such as MovePosition and MoveRotation, which use applied force.
I update the PlayerBehavior Csharp script and I add the FixedUpdate() method :
void FixedUpdate()
{
/* Any physics- or Rigidbody-related code always goes inside the FixedUpdate method,
rather than Update or the other MonoBehavior methods:
• FixedUpdate is frame rate independent and is used for all physics code
*/
Vector3 rotation = Vector3.up * _hInput;
// a new Vector3 variable to store our left and right rotations
Quaternion angleRot = Quaternion.Euler(rotation *
Time.fixedDeltaTime);
// Unity prefers quaternion Euler angles for rotation type
// see https://docs.unity3d.com/Documentation/Manual/QuaternionAndEulerRotationsInUnity.html
_rb.MovePosition(this.transform.position +
this.transform.forward * _vInput * Time.fixedDeltaTime);
/*The vector that’s used can be broken down as follows: the capsule’s Transform
position in the forward direction, multiplied by the vertical inputs and Time.
fixedDeltaTime
*/
_rb.MoveRotation(_rb.rotation * angleRot);
/*
angleRot already has the horizontal inputs from the keyboard, so all we need to
do is multiply the current Rigidbody rotation by angleRot to get the same left
and right rotation
*/
}
Quaternions provide mathematical notation for unique representations of spatial orientation and rotation in 3D space.
A quaternion uses four numbers to encode the direction and angle of rotation around unit axes in 3D. These four values are complex numbers rather than angles or degrees. You can look into the mathematics of quaternions for more information.
Unity converts rotational values to quaternions to store them because quaternion rotations are efficient and stable to compute.
Windows 11 v26100 Csharp First FPS moving the player : jump
Update of the C# script PlayerBehavior.cs to jump:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerBehavior : MonoBehaviour
{
public float MoveSpeed = 10f;
public float RotateSpeed = 75f;
private float _vInput;
private float _hInput;
public float JumpVelocity = 5f;
// hold the amount of applied jump force we want
private bool _isJumping;
// check if our player should be jumping
private Rigidbody _rb;
// https://docs.unity3d.com/ScriptReference/Rigidbody.html
void Start()
{
_rb = GetComponent<Rigidbody>();
// capture the RigidBody of the scene
}
void Update()
{
_isJumping |= Input.GetKeyDown(KeyCode.J);
// whether a specified key is pressed during the current frame and will
// only fire once even if J key held down
_vInput = Input.GetAxis("Vertical") * MoveSpeed;
_hInput = Input.GetAxis("Horizontal") * RotateSpeed;
/*
this.transform.Translate(Vector3.forward * _vInput *
Time.deltaTime);
this.transform.Rotate(Vector3.up * _hInput * Time.deltaTime);
*/
}
void FixedUpdate()
{
/* Any physics- or Rigidbody-related code always goes inside the FixedUpdate method,
rather than Update or the other MonoBehavior methods:
• FixedUpdate is frame rate independent and is used for all physics code
*/
Vector3 rotation = Vector3.up * _hInput;
// a new Vector3 variable to store our left and right rotations
Quaternion angleRot = Quaternion.Euler(rotation *
Time.fixedDeltaTime);
// Unity prefers quaternion Euler angles for rotation type
// see https://docs.unity3d.com/Documentation/Manual/QuaternionAndEulerRotationsInUnity.html
_rb.MovePosition(this.transform.position +
this.transform.forward * _vInput * Time.fixedDeltaTime);
/*The vector that’s used can be broken down as follows: the capsule’s Transform
position in the forward direction, multiplied by the vertical inputs and Time.
fixedDeltaTime
*/
_rb.MoveRotation(_rb.rotation * angleRot);
/*
angleRot already has the horizontal inputs from the keyboard, so all we need to
do is multiply the current Rigidbody rotation by angleRot to get the same left
and right rotation
*/
if (_isJumping)
{
// pass the Vector3 and ForceMode parameters to RigidBody.AddForce() and make the player jump
_rb.AddForce(Vector3.up * JumpVelocity, ForceMode.Impulse);
// Impulse applies instant force to an object while taking its mass into account
// https://docs.unity3d.com/ScriptReference/ForceMode.html
}
_isJumping = false;
// reset _isJumping to false so the input check knows a complete jump and the landing cycle have been completed
}
}
When i press F5 play, the player can now jump by pressing J. But while jumping if i press J again, the player will jump again, and so and so, and the player is flying because of the unlimited jumps. To ovoid that i’ll add a layer to test if the player is on the ground to be able to jump.
Windows 11 v26100 Csharp First FPS moving the player : prevent infinite jump "bug"
we’ll perform a simple check—whether the player capsule is touching the ground—in order to limit the player to one jump at a time
We need to detect when the player lands on the ground.
I select Herarchy/Environment/Ground, and in the inspector pane, layer default, i add layer, Ground
I choose the layer numer 6 and name it : Ground
Now i select the Hierarchy/Environment « group » and same operating mode : in the inspector, layer, i add, 6 : Ground.
Yes, change children.
Now i will check if the player intersec with the ground layer.
I modify the C# code in the PlayerBehavior.cs which became:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerBehavior : MonoBehaviour
{
// distance we’ll check between the player Capsule Collider and any Ground Layer object
public float DistanceToGround = 0.1f;
// use for the collider detection
public LayerMask GroundLayer;
// store the player’s Capsule Collider component
private CapsuleCollider _col;
public float MoveSpeed = 10f;
public float RotateSpeed = 75f;
private float _vInput;
private float _hInput;
public float JumpVelocity = 5f;
// hold the amount of applied jump force we want
private bool _isJumping;
// check if our player should be jumping
private Rigidbody _rb;
// https://docs.unity3d.com/ScriptReference/Rigidbody.html
void Start()
{
// find and return the Capsule Collider attached to the player
_col = GetComponent<CapsuleCollider>();
_rb = GetComponent<Rigidbody>();
// capture the RigidBody of the scene
}
void Update()
{
_isJumping |= Input.GetKeyDown(KeyCode.J);
// whether a specified key is pressed during the current frame and will
// only fire once even if J key held down
_vInput = Input.GetAxis("Vertical") * MoveSpeed;
_hInput = Input.GetAxis("Horizontal") * RotateSpeed;
/*
this.transform.Translate(Vector3.forward * _vInput *
Time.deltaTime);
this.transform.Rotate(Vector3.up * _hInput * Time.deltaTime);
*/
}
void FixedUpdate()
{
/* Any physics- or Rigidbody-related code always goes inside the FixedUpdate method,
rather than Update or the other MonoBehavior methods:
• FixedUpdate is frame rate independent and is used for all physics code
*/
Vector3 rotation = Vector3.up * _hInput;
// a new Vector3 variable to store our left and right rotations
Quaternion angleRot = Quaternion.Euler(rotation *
Time.fixedDeltaTime);
// Unity prefers quaternion Euler angles for rotation type
// see https://docs.unity3d.com/Documentation/Manual/QuaternionAndEulerRotationsInUnity.html
_rb.MovePosition(this.transform.position +
this.transform.forward * _vInput * Time.fixedDeltaTime);
/*The vector that’s used can be broken down as follows: the capsule’s Transform
position in the forward direction, multiplied by the vertical inputs and Time.
fixedDeltaTime
*/
_rb.MoveRotation(_rb.rotation * angleRot);
/*
angleRot already has the horizontal inputs from the keyboard, so all we need to
do is multiply the current Rigidbody rotation by angleRot to get the same left
and right rotation
*/
/* if (_isJumping)
{
// pass the Vector3 and ForceMode parameters to RigidBody.AddForce() and make the player jump
_rb.AddForce(Vector3.up * JumpVelocity, ForceMode.Impulse);
// Impulse applies instant force to an object while taking its mass into account
// https://docs.unity3d.com/ScriptReference/ForceMode.html
}
*/
_isJumping = false;
// reset _isJumping to false so the input check knows a complete jump and the landing cycle have been completed
// check whether IsGrounded returns true and the J key is pressed before executing the jump code
if (IsGrounded() && _isJumping)
{
_rb.AddForce(Vector3.up * JumpVelocity,
ForceMode.Impulse);
}
}
// method with a bool return type.
private bool IsGrounded()
{
// store the position at the bottom of the player’s Cap-sule Collider
Vector3 capsuleBottom = new Vector3(_col.bounds.center.x,
_col.bounds.min.y, _col.bounds.center.z);
// store the result of the CheckCapsule()
bool grounded = Physics.CheckCapsule(_col.bounds.center,
capsuleBottom, DistanceToGround, GroundLayer,
QueryTriggerInteraction.Ignore);
// return if the player is on the ground
return grounded;
}
}
Now, back to Unity user interface :
Hierarchy/player : In the inspector pane, i assign Ground layer : Ground .
Windows 11 v26100 Csharp First FPS moving the player : conclusion done
Done! i created the project Csharp First FPS moving the player, on windows 11 version 26100.
Windows 11 v26100 Csharp First FPS moving the player : need help ?
Need help with Windows 11 or C# with Unity?
Fill this form or send an email on loic @consultingit.fr or This email address is being protected from spambots. You need JavaScript enabled to view it. and i will be happy to help you :)