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血條跟隨。

如果小伙伴們有更好的方法,一定要記得分享啊!!!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM