Lykon
Lykon

Reputation: 33

Contoller script doesn't change direction when the character looks around

I'm using a controller script from the official Unity website to move my character around. I'm also using a script to turn the camera using the mouse. Everything works fine until the character looks around and faces a different direction. Then the WASD controls move them according to the original orientation. For example, if I turn 180 degrees W moves me backward and S moves me forward.

I've tried to figure this out using transform.forward but I don't really know what I'm doing.

The movement script:

CharacterController characterController;

public float speed = 6.0f;
public float jumpSpeed = 8.0f;
public float gravity = 20.0f;

private Vector3 moveDirection = Vector3.zero;

void Start()
{
    characterController = GetComponent<CharacterController>();
}

void Update()
{
    if (characterController.isGrounded)
    {
        // We are grounded, so recalculate
        // move direction directly from axes

        moveDirection = new Vector3(Input.GetAxis("Horizontal"), 0.0f, Input.GetAxis("Vertical"));
        moveDirection *= speed;

        if (Input.GetButton("Jump"))
        {
            moveDirection.y = jumpSpeed;
        }
    }

    // Apply gravity. Gravity is multiplied by deltaTime twice (once here, and once below
    // when the moveDirection is multiplied by deltaTime). This is because gravity should be applied
    // as an acceleration (ms^-2)
    moveDirection.y -= gravity * Time.deltaTime;

    // Move the controller
    characterController.Move(moveDirection * Time.deltaTime);
}

Thank you for any help :)

Upvotes: 1

Views: 674

Answers (2)

Radomyr Slaboshpitskyi
Radomyr Slaboshpitskyi

Reputation: 481

I's because Move uses world space coordinates but you generating local.

Try change

  moveDirection = new Vector3(Input.GetAxis("Horizontal"), 0.0f, Input.GetAxis("Vertical"));

to

  moveDirection = transform.right * Input.GetAxis("Horizontal") + transform.forward * Input.GetAxis("Vertical");

Upvotes: 0

Ruzihm
Ruzihm

Reputation: 20269

You can use Transform.TransformDirection to convert from local direction to world direction. Call that with the local direction you want to move and it will return the corresponding world direction which you can give to CharacterController.Move:

void Update()
{
    if (characterController.isGrounded)
    {
        // We are grounded, so recalculate
        // move direction directly from axes

        moveDirection = new Vector3(Input.GetAxis("Horizontal"), 0.0f, Input.GetAxis("Vertical"));
        moveDirection = transform.TransformDirection(moveDirection);
        moveDirection = moveDirection * speed;

        if (Input.GetButton("Jump"))
        {
            moveDirection.y = jumpSpeed;
        }
    }

    // Apply gravity. Gravity is multiplied by deltaTime twice (once here, and once below
    // when the moveDirection is multiplied by deltaTime). This is because gravity should be applied
    // as an acceleration (ms^-2)
    moveDirection.y -= gravity * Time.deltaTime;


    // Move the controller
    characterController.Move(worldMoveDirection * Time.deltaTime);
}

In fact, the old documentation for CharacterController.Move used this very method!

void Update()
{
    if (controller.isGrounded)
    {
        // We are grounded, so recalculate
        // move direction directly from axes

        moveDirection = new Vector3(Input.GetAxis("Horizontal"), 0.0f, Input.GetAxis("Vertical"));
        moveDirection = transform.TransformDirection(moveDirection);
        moveDirection = moveDirection * speed;

        if (Input.GetButton("Jump"))
        {
            moveDirection.y = jumpSpeed;
        }
    }

    // Apply gravity
    moveDirection.y = moveDirection.y - (gravity * Time.deltaTime);

    // Move the controller
    controller.Move(moveDirection * Time.deltaTime);
}

Upvotes: 1

Related Questions