Unity如何判斷遊戲物件是否在螢幕內,檢測玩家、NPC等是否在視野內
阿新 • • 發佈:2019-02-10
1、帶有Render的物體:
通過覆寫OnWillRenderObject來判斷被渲染的物體是否在視野內,但是對於不帶Render的物體無法檢測
2、座標轉換:
Unity提供的豐富的座標轉化機制,可以將GameObject的世界座標轉換為視野座標來判斷是否在視野內
1> 通過camera.WorldToViewportPoint(worldPos)將世界座標轉化為視窗座標
2> 視窗座標系為坐下角為(0,0),右上角為(1,1),只需判斷第一步轉換的座標viewPos的x、y是否在0-1之間即可
3> 判斷z值,在相機照射範圍內遠處的物體也可以判斷
4> 適當留一部分閾值
- //物體出現在螢幕
- void OnBecameVisible()
- {
- Debug.Log(this.name.ToString()+"這個物體出現在螢幕裡面了");
- }
- //物體離開螢幕
- void OnBecameInvisible()
- {
- Debug.Log(this.name.ToString() + "這個物體離開螢幕裡面了");
- }
using System.Collections; using System.Collections.Generic; using UnityEngine; /// <summary> /// 將指令碼掛在攝像機觀察的物體上 物體必須帶有Render /// </summary> public class PlayerView : MonoBehaviour { bool isRendering; float curtTime = 0f; float lastTime = 0f; void OnWillRenderObject() { curtTime = Time.time; } public bool IsInView(Vector3 worldPos) { Transform camTransform = Camera.main.transform; Vector2 viewPos = Camera.main.WorldToViewportPoint(worldPos); Vector3 dir = (worldPos - camTransform.position).normalized; float dot = Vector3.Dot(camTransform.forward, dir); //判斷物體是否在相機前面 if (dot > 0 && viewPos.x >= 0 && viewPos.x <= 1 && viewPos.y >= 0 && viewPos.y <= 1) return true; else return false; } void Update() { Vector2 vec2 = Camera.main.WorldToScreenPoint(this.gameObject.transform.position); if (IsInView(transform.position)) { Debug.Log("目前本物體在攝像機範圍內"); } else { Debug.Log("目前本物體不在攝像機範圍內"); } } }
public bool IsVisible(Bounds bounds, Camera camera)
{
// 得到攝像機的六個面
Plane[] planes = GeometryUtility.CalculateFrustumPlanes(camera);
// 判斷邊框bound是否在六個面內
return GeometryUtility.TestPlanesAABB(planes, bounds);
} 需要給遊戲物件新增Collider
if (GameDatabase.Instance.IsVisible(GetComponent().bounds, Camera.main))
{
Debug.Log("可見");
} else
{ //Debug.Log("不可見");
}