我想在屏幕上显示一个2D箭头,该箭头始终移动以指向AR场景中的3D对象。
问题是如何测量箭头旋转以指向所需3D对象的角度。
预先感谢。
答案 0 :(得分:1)
作为高级概述:
答案 1 :(得分:1)
一种策略是将对象的位置投影到屏幕空间中。 然后计算箭头位置和投影位置之间的向量。您可以使用该向量来计算点的旋转角度,例如,垂直方向,使用点积,后跟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);
}
对于上面的代码,我认为:
答案 2 :(得分:0)
使用Unity内置的Transform.LookAt函数
答案 3 :(得分: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);
}