Gerte
Gerte

Reputation: 97

How to properly use CharacterController.Move() to move the character

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

Answers (2)

Bizhan
Bizhan

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);

Performance note:

vector.normalized is obtained from vector/vector.magnitude and vector.magnitude is obtained from sqrt(vector.sqrMagnitude) which is heavy to process. To reduce the processing weight you can use vector/vector.sqrMagnitude instead of vector.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

hanoldaa
hanoldaa

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.

enter image description here

Upvotes: 2

Related Questions