网格表面周围的方向向量

时间:2019-03-07 13:04:24

标签: unity3d vector 3d transform

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

例如,假设下图所示的框位于原点(0,0,0)。如果我想将方框顶部的点移到左侧,则必须朝(-1,0,0)方向(即currentPos = currentPos + Vector3.left)迈出一步。

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

如果我从后面看箱子,则必须朝(1,0,0)方向迈出一步,才能继续朝同一方向移动。

即当我查看位于原点的此框并按输入按钮LEFT时,只要保持按住该按钮,我就需要使该点向左移动并继续沿该方向移动。最终它会包裹在表面上,也就是说,如果我一直向左按下,则该点将包裹在立方体上并重新出现。

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

2 个答案:

答案 0 :(得分: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 :(得分: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 here enter image description here