如何在屏幕上制作始终指向AR场景内的3d对象的2D箭头

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

我想在屏幕上显示一个2D箭头,它总是移动到指向AR场景中的3D对象。

问题是如何测量箭头旋转以指向所需3D对象的角度。 提前致谢。

unity3d augmented-reality vuforia
4个回答
1
投票

作为高级概述:

  • 查找从UI /视图平面中心到3D对象的方向
  • 项目方向到UI /视图平面(使用向前作为法向量),并进行标准化
  • 将2D箭头指向投影方向

1
投票

一种策略是将对象的位置投影到屏幕空间中。然后计算箭头位置和投影位置之间的向量。您可以使用此向量来计算旋转角度,例如,使用Dot Product,然后是acos来计算垂直方向。

最后,您需要进行一些交叉积计算,以确定上述旋转是顺时针还是逆时针。

以下是一些示例代码:

    public GameObject Target;

    RectTransform rt;

    void Start()
    {
        rt = GetComponent<RectTransform>();
    }

    void Update()
    {
        // Get the position of the object in screen space
        Vector3 objScreenPos = Camera.main.WorldToScreenPoint(Target.transform.position);

        // Get the directional vector between your arrow and the object
        Vector3 dir = (objScreenPos - rt.position).normalized;

        // Calculate the angle 
        // We assume the default arrow position at 0° is "up"
        float angle = Mathf.Rad2Deg * Mathf.Acos(Vector3.Dot(dir, Vector3.up));

        // Use the cross product to determine if the angle is clockwise
        // or anticlockwise
        Vector3 cross = Vector3.Cross(dir, Vector3.up);
        angle = -Mathf.Sign(cross.z) * angle;

        // Update the rotation of your arrow
        rt.localEulerAngles = new Vector3(rt.localEulerAngles.x, rt.localEulerAngles.y, angle);
    }

对于上面的代码,我想:

  • 您只使用一个主摄像头,您可能需要更改此设置
  • 您的箭头位于画布上,默认情况下指向上方(当旋转为(0,0,0)时)
  • 您在渲染模式下使用画布:屏幕空间 - 叠加。如果Canvas在World Space中,上面的代码会有所不同。

0
投票

使用Unity内置的Transform.LookAt功能


0
投票

谢谢所有人,我得到了两个情况的答案:第一个:当两个物体是3D时

    public GameObject flesh;
    public GameObject target;
    // Start is called before the first frame update
    void Start()
    {
        flesh.transform.position = Camera.main.ScreenToWorldPoint(new Vector3( Screen.width/2, Screen.height/2,1));
    }

    // Update is called once per frame
    void Update()
    {
        var dir = Camera.main.WorldToScreenPoint(target.transform.position) - 
        Camera.main.WorldToScreenPoint(flesh.transform.position);
        var angle = Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg;
        flesh.transform.rotation = Quaternion.AngleAxis(angle, Vector3.forward);
    }

第二:当肉体是具有RectTransform的图像时,这个解决方案鼓励来自@kevernicus

public GameObject Target;

    RectTransform rt;

    void Start()
    {
        rt = GetComponent<RectTransform>();
    }

    void Update()
    {
        // Get the position of the object in screen space
        Vector3 objScreenPos = Camera.main.WorldToScreenPoint(Target.transform.position);

        // Get the directional vector between your arrow and the object
        Vector3 dir = (objScreenPos - rt.position).normalized;

        float angle = Mathf.Rad2Deg * Mathf.Atan2(dir.y, dir.x);


        rt.rotation = Quaternion.AngleAxis(angle, Vector3.forward);
    }
© www.soinside.com 2019 - 2024. All rights reserved.