проблемы понимания движения по локальному и глобальному пространству в единстве - PullRequest
2 голосов
/ 07 октября 2019
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);

У меня есть игрок, который вращается, и я хочу заставить его двигаться в своем локальном направлении, но я не понимаю, когда я удаляю movement = transform.TransformDirection(movement); из кода, он перемещается в глобальное направление, что не имеет никакого смыслапотому что эта строка кода преобразует направление из локального в глобальное пространство.

Ответы [ 2 ]

1 голос
/ 07 октября 2019

Это потому, что 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);
    }
}
1 голос
/ 07 октября 2019

Ваш movement вектор находится в локальном пространстве

Вы хотите, чтобы игрок двигался вперед локально и двигался горизонтально локально , и поэтому вы строите вперед / вправоmovement вектор на основе входных данных игрока. Этот вектор находится в локальных координатах, и вы TransformDirection возвращаетесь в мир пробел, прежде чем применить результат к позиции мир с _charController.Move (предположительно, вы невключите код этого метода).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...