向transform.forward移动,忽略旋转

时间:2017-01-04 12:38:01

标签: c# unity3d

此代码附在相机上:

transform.position += Input.GetAxis("Vertical") * transform.forward * mod;
transform.position += Input.GetAxis("Horizontal") * transform.right * mod;

我使用了.forward和.right,因为玩家可以在Y轴上旋转相机,因此无论相机朝向前进键的哪个方向都会相机向前移动,左边键会相对左移等等。只是为了澄清 - 我希望它移动到本地空间,而不是世界空间,所以前进是它所面对的方向,不一定是Vector3(0,0,1)。

相机是自由漫游的,没有父母或目标可供使用。

问题是相机的X旋转为45以向下看。因此,使用transform.forward将修改它的高度。还有一些滚动代码可以更改相机高度,因此我不想将高度设置为固定值。我怎样才能限制移动到X和Z,最好不要将它变成空的?

更新:此代码有效,但它并不漂亮,我确信使用Vector3.Project有一个更优雅的解决方案,正如xyLe_所暗示的那样。如果我弄清楚,我会添加他的答案。

mod = Time.deltaTime * 30;
float yPos = transform.position.y;
pos = transform.position;
pos += Input.GetAxis("Vertical") * transform.forward * mod;
pos.y = yPos;
pos += Input.GetAxis("Horizontal") * transform.right * mod;
pos += Input.GetAxis("Mouse ScrollWheel") * transform.up * mod * -30;

2 个答案:

答案 0 :(得分:4)

我现在可能会胡说八道,但对我来说似乎很简单:

Vector3 desiredDirection = Vector3.Normalize(new Vector3(transform.forward.x, transform.position.y, transform.forward.z))

只需将transform.forward投影到transform.position.y高度的x-z平面上。这样做(通常)会导致矢量略短,因此您必须重新规范化它。

要想象:

vec img

如果我理解正确,transform.forward对应黑色矢量,你想拥有绿色矢量。通过将黑色矢量的y分量设置为红色点位y分量的y分量,可以得到紫色矢量,该矢量必须重新规范化。

答案 1 :(得分:0)

即使已经解决了这个问题,下面的解决方案也可以帮助其他人解决这个问题。

这是向transform.forward移动而忽略其旋转的正确方法:

1 。获取transform.forward

2 。使用InverseTransformDirection

将其转换为本地空间

3 。将y轴设置为0;

4 。使用dir.Normalize();

对其进行规范化

5 。将新位置添加到transform.position

public float mod = 2;

void Update()
{
    //Get Forward face
    Vector3 dir = transform.forward;
    //Convert to local Space
    dir = transform.InverseTransformDirection(dir);
    //Reset/Ignore y axis
    dir.y = 0;
    dir.Normalize();

    //Append the new pos to the `transform.position`.
    transform.position += dir * Input.GetAxis("Vertical") * mod;
    transform.position += Input.GetAxis("Horizontal") * transform.right * mod;
}

另一种方法(不推荐):

由于相机倾斜角度为45°:

1 。将其转到-45

2 。正常移动相机

3 。将其重新转回45

public float startingOffset = 45;
public float mod = 2;


// Update is called once per frame
void Update()
{
    //Rotate it to -45
    transform.Rotate(new Vector3(-startingOffset, 0, 0));

    // Move the camera normally
    transform.position += Input.GetAxis("Vertical") * transform.forward * mod;
    transform.position += Input.GetAxis("Horizontal") * transform.right * mod;

    //Rotate it back to 45
    transform.Rotate(new Vector3(startingOffset, 0, 0));
}

这两种方法都应该有效,但首选应该是第一种方法。