模型标签一直朝向摄像机,无论相机拉远拉近标签大小不变。
using UnityEngine;
public class Billboard : MonoBehaviour
{
[SerializeField]
private bool isScaleSize; // 是否根据距离来缩放大小
[SerializeField]
private float baseDistance = 10f; // 给定距离相机的参考距离。在该距离下的UI大小是我们想要的
public Camera mainCamera; // 游戏主相机
private Camera MainCamera
{
get
{
if (mainCamera == null)
{
mainCamera = Camera.main;
}
return mainCamera;
}
}
private Vector2 baseScale; // 原本的缩放比例
private void Start()
{
baseScale = transform.localScale;
}
void Update()
{
transform.forward = MainCamera.transform.forward;
transform.rotation = MainCamera.transform.rotation;
}
private void LateUpdate()
{
// 令自身旋转值和相机的旋转值保持一致,使UI始终面向相机
//transform.rotation = MainCamera.transform.rotation;
if (isScaleSize)
{
var scale = CalcScale();
if (scale.x <= 2)
{
scale = new Vector2(2, 2);
}
transform.localScale = new Vector3(scale.x, scale.y, 2);
}
}
// 根据Canvas相对于相机的垂直距离和参考距离的比,来计算出新的缩放比例
private Vector2 CalcScale()
{
// 计算出自身在相机坐标系内的局部坐标,此时局部坐标的Z值即为自身到相机的垂直距离
var posInCamera = MainCamera.transform.InverseTransformPoint(transform.position);
// 使用当前垂直距离比上参考距离,即可得出需要缩放的比例
var rate = posInCamera.z / baseDistance;
// 用原本的缩放比例乘以需要缩放的比例,得到最终缩放比例
return baseScale * rate;
}
}