咱们在作HUD时常常使用物体的位置做为世界坐标点, 这在小物体的状况下没有问题, 可是在对于大型物体就有点麻烦, 由于咱们的视角不必定能看到该点, html
好比大楼, 大桥甚至公路等, 但愿能在物体进入视线范围内时获取一个当前视线范围内该物体离屏幕中心最近的一个点, 做为HUD的世界坐标点来显示.ide
1. 首先须要测试物体是否在可视范围内, 通常使用 OnBecameVisible() 生命周期便可.测试
2. 获取可视范围内离屏幕中心最近的点, 这个能够是多边形面上某点, 不必定是多边形的点.rest
3. 由于视角是个三角形, 因此非规则物体常常是离相机最近的点不在相机视角以内.orm
4. 不能作的太复杂htm
因而咱们从生命周期开始作, 在进入相机视角时添加到某个列表中, 由于依赖于Collider的API 而且需求该Collider为凸多边形, 因此对MeshCollider进行判断blog
private void OnBecameVisible() { var collider = GetComponent<Collider>(); if(collider) { var mc = collider as MeshCollider; if(mc && mc.convex == false) { return; } visibleColliders.Add(collider); } }
而后由于相机是移动的, 计算位置也须要Update生命周期
public static IEnumerator Run() { while(true) { if(visibleColliders.Count > 0) { foreach(var visibleCollider in visibleColliders) { var nearestPoint = visibleCollider.ClosestPoint(GetCameraViewPoint(visibleCollider)); onVisible.Invoke(visibleCollider, nearestPoint); } } yield return null; } }
关键就是计算离屏幕中心最近的位置了, 由于屏幕中心能够作一条射线出去, 这就是屏幕中心的线段, 按照理论 : 不必定有一个顶点必定会在屏幕视线范围内.get
这个比较好理解吧, 一个面通过相机视线, 但是全部点都不在相机视线范围内, 因此简单数学方法获取离线段最近的点没有意义.数学
这里就用Collider自带的API来计算一个大概的值便可:
private static Vector3 GetCameraViewPoint(Collider target) { var dis = (Camera.main.transform.position - target.bounds.center).magnitude; var pos = Camera.main.transform.position + Camera.main.transform.forward * dis; return pos; }
这里使用相机到物体的中心位置的距离做为参考, 从相机发射的射线在这个距离的点进行计算, 而后计算该点到物体的最近位置, 所获得的位置就做为HUD世界坐标,
在大部分状况下是符合逻辑的...
视屏没法设置, 传土豆去了
https://v.youku.com/v_show/id_XNDE4Mzc5MTU5Mg==.html?spm=a2h3j.8428770.3416059.1