Reputation: 33
CharacterController _charController;
// ...
moveInputX = Input.GetAxis("Horizontal") * speed;
moveInputZ = Input.GetAxis("Vertical") * speed;
Vector3 movement = new Vector3(moveInputX, 0, moveInputZ);
movement = Vector3.ClampMagnitude(movement, speed);
movement.y = -9.81f;
movement *= Time.deltaTime;
movement = transform.TransformDirection(movement);
_charController.Move(movement);
I have a player that rotates and I want to make him move to his local direction but i don't understand when I remove movement = transform.TransformDirection(movement);
from the code it moves to global direction which doesn't make any sense because this line of code converts the direction from local to global space.
Upvotes: 2
Views: 2220
Reputation: 20249
It's because CharacterController.Move
expects a vector in world space. Sadly, the documentation on that has never been clear about that.
When you calculate movement
here:
Vector3 movement = new Vector3(moveInputX, 0, moveInputZ);
You can see that it doesn't take the rotation of the character's transform into account. In order for it to do that, you want to find what this vector looks like in world space when interpreted as being in the character's local space. That's exactly what this line does:
movement = transform.TransformDirection(movement);
It converts movement
from local space to world space.
The 2018.1 CharacterController.Move
documentation actually uses transform.TransformDirection
in its example:
using UnityEngine; using System.Collections; // The GameObject is made to bounce using the space key. // Also the GameOject can be moved forward/backward and left/right. // Add a Quad to the scene so this GameObject can collider with a floor. public class ExampleScript : MonoBehaviour { public float speed = 6.0f; public float jumpSpeed = 8.0f; public float gravity = 20.0f; private Vector3 moveDirection = Vector3.zero; private CharacterController controller; void Start() { controller = GetComponent<CharacterController>(); // let the gameObject fall down gameObject.transform.position = new Vector3(0, 5, 0); } 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
Reputation: 15941
movement
vector is in local spaceYou want the player to move forward locally and move horizontally locally and so you construct a forward/rightward movement
vector based on the player input. This vector is in local coordinates and you TransformDirection
back to world space before applying the result to world position with _charController.Move
(presumably, you didn't include that method's code).
Upvotes: 1