摘要:本文原創,轉載請注明出處: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血條跟隨。
如果小伙伴們有更好的方法,一定要記得分享啊!!!