来自 transform.InverseTransformDirection 的玩家意外移动

Unintended player movement from transform.InverseTransformDirection

这是我第一次在这里发帖。我正在使用新的 Unity 多人网络解决方案开发游戏。 总之,问题是玩家没有按预期移动。

我正在尝试按以下方式获取玩家输入:

Vector3 worldSpaceDir = new Vector3(Input.GetAxisRaw("Vertical"), 0, Input.GetAxisRaw("Horizontal"));

然后将其转化为玩家角色的对象space坐标:

_inputDirection = transform.InverseTransformDirection(worldSpaceDir);

我遇到的问题是旋转 0 度或 180 度时玩家按照 WASD 输入的预期移动,但是,在 90 度或 270 度时所有输入都被翻转(A = 右,D = 左,W = 向后,S = 向前)。

我发现一个问题正是我的问题,但没有人回答。这个问题现在已经很老了所以我想再问一次以获得更多可见性。

Here's a link to the original question.

我想你实际上想反过来!

Transform.InverseTransformDirection 将来自世界 space 的向量转换为本地 space.

然而,您得到的输入是 XZ 平面上的 local 矢量。你想根据你的玩家对象方向应用这个方向,例如向右按(您的输入是 1,0,0)对象将向其 transform.right 向量移动。

所以你宁愿在相反的方向转换成世界space来移动Unity世界中的对象space。

你应该使用 Transform.TransformDirection!

var worldMove = transform.TransformDirection(input);

或者你也可以像

一样乘以旋转
var worldMove = transform.rotation * input;

请注意,如果您也像您链接的问题一样使用 Rigidbody,那么还有 Rigidbody.AddRelativeForce 基本上以相同的方式工作,并需要一个本地 space 向量,然后在内部将其转换为世界space力。

首先,你把worldSpaceDir理解错了,应该如下

Vector3 worldSpaceDir = new Vector3(Input.GetAxisRaw("Horizontal"), 0, Input.GetAxisRaw("Vertical"));

这里我们取水平输入为X,垂直输入为Z,因为在Unity中Forward是指向Z而不是Y。

其次,我们不需要使用 InverseTransformDirection() 我们只需要 TransformDirection() 像下面这样的东西

Vector3 inputDirection = transform.TransformDirection(worldSpaceDir);

这里我们告诉unity将相对于transform(本地方向)的worldSpaceDir转换为世界space方向,所以我们实际上可以给一个合适的名字worldSpaceDir.

以下内容适合您。

private void Update() {
    Move();
}

private void Move() {
    Vector3 directionToMove = new Vector3(Input.GetAxisRaw("Horizontal"), 0, Input.GetAxisRaw("Vertical"));
    Vector3 inputDirection = transform.TransformDirection(directionToMove);
    transform.position += inputDirection * Time.deltaTime;
}