实现原理:在Update函数里面将3D对象的位置坐标转化为屏幕坐标,然后再赋值给UI对象,这样UI对象还是实时跟随3D对象。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Diagnostics;
public class UIFollow : MonoBehaviour
{
GameObject currentObj;
GameObject BGContent;
public Vector2 offset;
public GameObject Target;
void Start()
{
BGContent = GameObject.Find("BGContent");
}
private void Update()
{
// 如果目标对象在相机视野中
if (IsVisableInCamera(Target.transform.position))
{
// 激活背景内容
BGContent.transform.gameObject.SetActive(true);
// 获取目标对象的屏幕位置
BGContent.GetComponent<RectTransform>().anchoredPosition = GetScreenPosition(Target.transform.position);
}
else
{
// 否则,关闭背景内容
BGContent.transform.gameObject.SetActive(false);
}
}
public Vector2 GetScreenPosition(Vector3 v3)
{
// 将屏幕坐标转换为世界坐标
Vector3 viewportPos = new Vector3();
viewportPos = Camera.main.WorldToViewportPoint(v3);
// 获取Canvas组件
Transform ca = GameObject.Find("Canvas").transform;
// 获取Canvas的RectTransform组件
RectTransform canvasRtm = ca.GetComponent<RectTransform>();
// 定义一个Vector2变量,用于存储最终的Ugui坐标
Vector2 uguiPos = Vector2.zero;
// 将屏幕坐标转换为Ugui坐标
uguiPos.x = (viewportPos.x - offset.x) * canvasRtm.sizeDelta.x;
uguiPos.y = (viewportPos.y - offset.y) * canvasRtm.sizeDelta.y;
// 返回最终的Ugui坐标
return uguiPos;
}
public bool IsVisableInCamera(Vector3 v3)
{
// 获取主相机
Camera mCamera = Camera.main;
// 将给定的点从世界坐标转换为视口坐标
Vector3 viewPos = mCamera.WorldToViewportPoint(v3);
// 如果视口坐标的z轴小于0,则返回false
if (viewPos.z < 0) return false;
// 如果视口坐标的z轴大于主摄像机的farClipPlane,则返回false
if (viewPos.z > mCamera.farClipPlane)
return false;
// 如果视口坐标的x轴小于0,或者y轴小于0,或者x轴大于1,或者y轴大于1,则返回false
if (viewPos.x < 0 || viewPos.y < 0 || viewPos.x > 1 || viewPos.y > 1) return false;
// 否则返回true
return true;
}
}