/// <summary>
/// 判断物体的坐标是否在相机前方
/// </summary>
/// <param name="worldPos"></param>
/// <returns></returns>
public bool IsInView(Vector3 worldPos)
{
Transform camTransform = Camera.main.transform;
Vector2 viewPos = Camera.main.WorldToViewportPoint(worldPos);
Vector3 dir = (worldPos - camTransform.position).normalized;
float dot = Vector3.Dot(camTransform.forward, dir);//判断物体是否在相机前面
if (dot > 0 && viewPos.x >= 0 && viewPos.x <= 1 && viewPos.y >= 0 && viewPos.y <= 1)
return true;
else
return false;
}
/// <summary>
/// 3D坐标转UI坐标
/// </summary>
/// <param name="position"></param>
/// <returns></returns>
public static Vector2 WorldToUgui(Vector3 position)
{
Vector2 screenPoint = Camera.main.WorldToScreenPoint(position);//世界坐标转换为屏幕坐标
Vector2 anchorPos = Vector2.zero;
//UI设置为Screen Space - Camera 模式 然后设置一个UI相机
RectTransformUtility.ScreenPointToLocalPointInRectangle(Canvas.transform as RectTransform, screenPoint,Canvas.worldCamera, out anchorPos);
return anchorPos;
}
具体使用案例:
void Update()
{
for (int i = 0; i < marker3Ds.Count; i++) //持有一个3d物体List,每帧遍历
{
if (marker3Ds[i].MarkerUI != null) //物体上持有对应UI
{
if (IsInView(marker3Ds[i].transform.position))
{
marker3Ds[i].MarkerUI.gameObject.SetActive(true);
((RectTransform)marker3Ds[i].MarkerUI.transform).anchoredPosition = WorldToUgui(marker3Ds[i].transform.position);
}
else
{
marker3Ds[i].MarkerUI.gameObject.SetActive(false); //避免相机后面物体UI显示在屏幕上
}
}
}
}