日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

怪物AI之发现玩家(视觉范围发现系列)

發布時間:2023/12/20 46 豆豆
生活随笔 收集整理的這篇文章主要介紹了 怪物AI之发现玩家(视觉范围发现系列) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在網上找到一些資料參考,然后寫寫自己的想法。
這里感謝MOMO等大神。

我們用玩家檢測怪物的方法來測,這樣比較試用與弱聯網游戲,每次在同步玩家的時候來判斷玩家與怪物的位置。
這里給出兩個處理方式:
1.碰撞器R范圍檢測。
2.地圖分塊范圍檢測。

這兩種處理方式適用于不同的游戲。
再講解這兩種方式之前,我們先了解一下一個核心問題,怪物在玩家R半徑內時怎么判斷怪物是否在玩家視覺范圍內。
如下圖

在圖中,
玩家的位置與怪物的位置會成一個向量。設為V1
怪物的朝向也是一個向量。設為V2
如果怪物能看到60°的角度的話。那么Vector(V1,V2)如果小于30°則證明玩家在怪物的視覺范圍內。
代碼為:

private bool Find(GameObject _Monster){Vector3 otherPos = _Monster.gameObject.transform.position;v = transform.position - otherPos;v.y = 0.5f; //處理一下y軸,因為判斷建立在二維上w = _Monster.gameObject.GetComponent<FindPlayerAI>().getFace() - otherPos;w.y = 0.5f;if (Vector3.Angle(v, w) < 30){return true;}return false;}

PS:如果想在三維上進行判斷的話,同理在處理一下yz軸平面就ok了。

現在我們講解一下第一種處理方式:
這種比較簡單也很無腦。給Player加一個SphereCollider就好了,而且這樣也可以判斷三維狀態。注:如果用Terrain做地面請屏蔽。
碰撞器代碼:

void OnTriggerEnter(Collider other){if (!other.name.Equals("Terrain")){if (Find(other.gameObject)) //接上一個Find代碼{Debug.Log("發現");}}}

然后就是第二種比較有想法的方式了。
將游戲地圖分塊。如下圖

這里呢。大體思路為:
玩家在0號塊,在這個狀態的時候,只有a,b怪物可以與玩家進行角度判斷,cdef都忽略掉。
代碼如下:
Map.cs:

public class Map : MonoBehaviour{private static Map _Instance;public static Map Instance{get{if (_Instance == null){_Instance = new GameObject("_Map").AddComponent<Map>();}return _Instance;}}private int PlayerPos = -1;private GameObject[][] Monster = new GameObject[100][];private int[] MonsterNum = new int[100];//public int n = 0;void Awake(){ for (int i = 0; i < 100; i++){Monster[i] = new GameObject[10];MonsterNum[i] = 0;}}int getPos(GameObject go){float x = go.transform.position.x;float z = go.transform.position.z;x /= 20;z /= 20;int pos = (int)(Mathf.Floor(x) + Mathf.Floor(z) * 10);return pos;}public void setMonsterPos(GameObject _Monster){int pos = getPos(_Monster);Monster[pos][MonsterNum[pos]++] = _Monster;Debug.Log(pos + _Monster.name);}public int getPlayerPos(GameObject _Player){int pos = getPos(_Player);if (PlayerPos == pos){return -1;}else{PlayerPos = pos;}return pos;}public GameObject[] getMonster(int pos){return Monster[pos];}}

玩家AI.cs:

public class PlayerAI : MonoBehaviour {Vector3 v;Vector3 w;Vector3 otherPos;GameObject[] Monster = new GameObject[10];private bool Find(GameObject _Monster){otherPos = _Monster.gameObject.transform.position;v = transform.position - otherPos;v.y = 0.5f;w = _Monster.gameObject.GetComponent<MonsterAI>().getFace() - otherPos;w.y = 0.5f;if (Vector3.Angle(v, w) < 30){return true;}return false;}//void OnTriggerEnter(Collider other)//{// if (!other.name.Equals("Terrain"))// {// if (Find(other.gameObject))// {// Debug.Log("發現");// }// }//}void Update(){int pos = Map.Instance.getPlayerPos(gameObject);if (pos != -1){Monster = Map.Instance.getMonster(pos);}for (int i = 0; i < Monster.Length; i++){if (Monster[i] != null){if (Find(Monster[i])){Debug.Log(i + "發現");}}}} }

怪物AI.cs:

public class MonsterAI : MonoBehaviour {public GameObject Player;private Vector3 Face;void Start () {Face = transform.position + transform.rotation * Vector3.forward * 10;Map.Instance.setMonsterPos(gameObject);}public Vector3 getFace(){return Face;}void Update(){Face = transform.position + transform.rotation * Vector3.forward * 10;//Debug.DrawLine(transform.position, Face, Color.red);} }

總結

以上是生活随笔為你收集整理的怪物AI之发现玩家(视觉范围发现系列)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。