Reputation: 33
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
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
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