网格表面周围的方向向量

问题描述 投票:0回答:2

如何最好地描述方向向量以将对象从其当前位置向左(或向右/向上/向下)移动,将当前视图视角分解为等式?

例如,想象下图中描绘的框,放置在原点(0,0,0)。如果我想把盒子顶部的点移到左边,我必须向(-1,0,0)方向迈出一步(即currentPos = currentPos + Vector3.left)。

Vector Left(-1,0,0) when viewing from front

如果我从后面看着盒子,我必须向(1,0,0)方向迈出一步,继续向同一方向移动。

即当我看着这个放置在原点的盒子并按下左侧的输入按钮时,我需要向左移动并继续向该方向移动,只要我一直按下按钮。它最终包裹在表面周围,即如果我一直按下左边,点将围绕立方体重新出现并重新出现。

Vector Left(1,0,0) when viewing from behind

unity3d vector 3d transform
2个回答
2
投票

无限制地追踪立方体周围的贴花:

private Transform Cube;
private Transform Decal;


void Update() {


    Vector3 moveLocal = Vector3.zero;

    // Set moveLocal from User Input
    moveLocal += Vector3.left * Input.GetAxis("Left"); // etc

    if (moveLocal.sqrMagnitude > 0) {

        var decalDirection = (Decal.position - Cube.position).normalized;
        var angle = Vector3.SignedAngle(Cube.forward, decalDirection, Cube.up);


        // Align decal to correct cube face
        if (angle < -135 || angle > 135) { // Rear face
            Decal.forward = -Cube.forward;
        }
        else if (angle < -45) { // Left face
            Decal.forward = -Cube.right;
        }
        else if (angle > 45) { // Right face
            Decal.forward = Cube.right;
        }
        else { // Front Face
            Decal.forward = Cube.forward;
        }

        // Now move decal in it's local space:
        Decal.Translate(moveLocal, Space.Self);
    }
}

不可否认,这只是向左/向右旋转,但我希望你能得到这个想法=)


1
投票

正如我在我看来提到的那样,你可以用表面法线来实现这一点。我破解了一些不是一个精确解决方案的代码,因为我使用了碰撞法线和在角落上提供了不同的结果。在任何情况下,我分享它,以便它给你的想法。您可以使用此代码相对于相机向左和向右移动(即使它不使用与相机相关的任何内容),因为它取决于表面法线。

private Vector3 normal;
private Vector3 contact;
private Vector3 direction;
private GameObject obj;

void Start () {

}

void Update () {
    if (obj == null)
        return;
    if( Input.GetKey(KeyCode.LeftArrow))
    {
        obj.transform.position += direction * Time.deltaTime;
    }
    if (Input.GetKey(KeyCode.RightArrow))
    {
        obj.transform.position -= direction * Time.deltaTime;
    }
}

void OnCollisionEnter(Collision collision)
{
    Debug.Log("Collided");

    Debug.Log("If works");
    obj = collision.gameObject;
    normal = collision.contacts[0].normal;
    contact = collision.contacts[0].point;

    //Cross product of normal and up gives direction Right. 
    //This up can be cube's up as well in cases it is tilted
    direction = (-Vector3.Cross(Vector3.up, normal));

}

您还可以从下面的图像中看到它的工作原理:

enter image description hereenter image description here

© www.soinside.com 2019 - 2024. All rights reserved.