Это потому, что CharacterController.Move
ожидает вектор в мировом пространстве. К сожалению, документация по этому вопросу никогда не была ясной.
Когда вы вычисляете movement
здесь:
Vector3 movement = new Vector3(moveInputX, 0, moveInputZ);
Вы можете видеть, что не учитывается поворот преобразования персонажа. Чтобы это сделать, вы хотите найти, как этот вектор выглядит в мировом пространстве, когда интерпретируется как находящийся в локальном пространстве персонажа. Это именно то, что делает эта строка:
movement = transform.TransformDirection(movement);
Она преобразует movement
из локального пространства в мировое пространство.
Документация 2018.1 CharacterController.Move
фактически использует transform.TransformDirection
в своем примере:
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);
}
}