Unity 检测物体是否在相机视野范围内
摘要:本文原创,转载请注明出处:http://www.cnblogs.com/AdvancePikachu/p/6733620.html
需求:
类似NPC血条,当NPC处于摄像机视野内,血条绘制,且一直保持在NPC头顶。
开始:
网上查找资料,然后编写代码:
public RectTransform rectBloodPos; void Update () { this.gameObject.transform.Translate (Input.GetAxis ("Horizontal") * 10 * Time.deltaTime, 0, 0); this.gameObject.transform.Translate (0, 0, Input.GetAxis ("Vertical") * 10 * Time.deltaTime); Vector2 vec2 = Camera.main.WorldToScreenPoint (this.gameObject.transform.position); rectBloodPos.anchoredPosition = new Vector2 (vec2.x - Screen.width / 2 + 0, vec2.y - Screen.height / 2 + 60); }
实现效果图:
但是随后发现,若摄像机背对物体则如下图:
什么鬼,居然凭空出现UI,后来研究改进:
1 bool isRendering; 2 float curtTime=0f; 3 float lastTime=0f; 4 5 void OnWillRenderObject() 6 { 7 curtTime = Time.time; 8 } 9 10 void Update () 11 { 12 isRendering = curtTime != lastTime?true:false; 13 14 Vector2 vec2 = Camera.main.WorldToScreenPoint (this.gameObject.transform.position); 15 if (isRendering) 16 { 17 rectBloodPos.gameObject.SetActive (true); 18 rectBloodPos.anchoredPosition = new Vector2 (vec2.x - Screen.width / 2 + 0, vec2.y - Screen.height / 2 + 60); 19 } 20 else 21 rectBloodPos.gameObject.SetActive (false); 22 23 lastTime = curtTime; 24 25 }
这种方法的原理是,当摄像机范围内出现挂有该脚本的物体,且该物体上存在Render组件的,则触发绘制UI。
虽然这个方法很好用,但是由于物体太多后,影响性能,故再次改进:
1 public bool IsInView(Vector3 worldPos) 2 { 3 Transform camTransform = Camera.main.transform; 4 Vector2 viewPos = Camera.main.WorldToViewportPoint (worldPos); 5 Vector3 dir = (worldPos - camTransform.position).normalized; 6 float dot = Vector3.Dot (camTransform.forward, dir);//判断物体是否在相机前面 7 8 if (dot > 0 && viewPos.x >= 0 && viewPos.x <= 1 && viewPos.y >= 0 && viewPos.y <= 1) 9 return true; 10 else 11 return false; 12 } 13 14 void Update () 15 { 16 Vector2 vec2 = Camera.main.WorldToScreenPoint (this.gameObject.transform.position); 17 18 if (IsInView (transform.position)) 19 { 20 rectBloodPos.gameObject.SetActive (true); 21 rectBloodPos.anchoredPosition = new Vector2 (vec2.x - Screen.width / 2 + 0, vec2.y - Screen.height / 2 + 60); 22 } 23 else 24 rectBloodPos.gameObject.SetActive (false); 25 }
这个方法是用Vector3.Dot()的方法判断摄像机与物体的朝向以及前后从而判定是否显示UI。
以上完美实现NPC血条跟随。
如果小伙伴们有更好的方法,一定要记得分享啊!!!
你有什么资格不努力!——进击的皮卡丘