Reputation: 97
I created a basic First Person Controller but my problem is when i move both forward and sideways i move faster.
How can i add moveDirectionForward
and moveDirectionSide
in 1 Vector3 to be able to use CharacterController.Move()
instead of CharacterController.SimpleMove()
?
void MovePlayer() {
// Get Horizontal and Vertical Input
float horizontalInput = Input.GetAxis ("Horizontal");
float verticalInput = Input.GetAxis ("Vertical");
// Calculate the Direction to Move based on the tranform of the Player
Vector3 moveDirectionForward = transform.forward * verticalInput * walkSpeed * Time.deltaTime;
Vector3 moveDirectionSide = transform.right * horizontalInput * walkSpeed * Time.deltaTime;
// Apply Movement to Player
myCharacterController.SimpleMove (moveDirectionForward + moveDirectionSide);
Upvotes: 2
Views: 20919
Reputation: 17085
The solution is to use a normalized vector for the direction of the movement.
// Get Horizontal and Vertical Input
float horizontalInput = Input.GetAxis ("Horizontal");
float verticalInput = Input.GetAxis ("Vertical");
// Calculate the Direction to Move based on the tranform of the Player
Vector3 moveDirectionForward = transform.forward * verticalInput;
Vector3 moveDirectionSide = transform.right * horizontalInput;
//find the direction
Vector3 direction = (moveDirectionForward + moveDirectionSide).normalized;
//find the distance
Vector3 distance = direction * walkSpeed * Time.deltaTime;
// Apply Movement to Player
myCharacterController.Move (distance);
vector.normalized
is obtained fromvector/vector.magnitude
andvector.magnitude
is obtained fromsqrt(vector.sqrMagnitude)
which is heavy to process. To reduce the processing weight you can usevector/vector.sqrMagnitude
instead ofvector.normalized
but be ware the result is not exactly the same, but still is in the same direction.
now i just need to apply gravity
Subtract moveDirection.y
by the gravity multiplied by Time.deltaTime
.
You can also simplify and reduce the code in the MovePlayer
function by using Vector3
and TransformDirection
.
public float walkSpeed = 10.0f;
private Vector3 moveDirection = Vector3.zero;
public float gravity = 20.0F;
CharacterController myCharacterController = null;
void Start()
{
myCharacterController = GetComponent<CharacterController>();
}
void MovePlayer()
{
moveDirection = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
moveDirection = transform.TransformDirection(moveDirection);
moveDirection *= walkSpeed;
moveDirection.y -= gravity * Time.deltaTime;
myCharacterController.Move(moveDirection * Time.deltaTime);
}
Upvotes: 6
Reputation: 616
You will want to use the normalized vector of the two axes when you multiply by your walkSpeed
. The reason being is this will ensure that you always move in any direction with the same magnitude (1) no matter the angle. Whereas your current setup has non-orthogonal movement being being calculated at >1 magnitude. So something like this should work in your situation.
void MovePlayer()
{
// Get Horizontal and Vertical Input
float horizontalInput = Input.GetAxis("Horizontal");
float verticalInput = Input.GetAxis("Vertical");
// Calculate the Direction to Move based on the tranform of the Player
Vector3 moveDirectionForward = transform.forward * verticalInput * Time.deltaTime;
Vector3 moveDirectionSide = transform.right * horizontalInput * Time.deltaTime;
// Apply Movement to Player
myCharacterController.SimpleMove((moveDirectionForward + moveDirectionSide).normalized * walkspeed);
Simply move the walkSpeed multiplication to the SimpleMove call against the normalized vector. The image below should help to visualize the problem you're having. By normalizing the vector before applying the walk speed, you're making sure that the direction vector is the same magnitude (effectively distance in this case) no matter what direction before you apply the walk speed.
Upvotes: 2