unity3d WayPoint路點尋路,AI
阿新 • • 發佈:2019-01-29
前言
一個簡單的人工智慧WayPoint
WayPoint: 遊戲中敵人根據幾個巡邏點自動巡邏,在巡邏過程中,時刻監聽英雄(敵人)和自己距離是否達到追擊範圍(不巡邏,追擊英雄),在追擊過程中,監聽是否達到攻擊範圍(不追擊,攻擊)。
所需物件
- 當前玩家
- 敵人
- 3個巡邏點
每個物件的指令碼
指令碼類
1.巡邏點 ,這裡給每個巡邏點新增這個類,並拖入這個巡邏點的下一個巡邏點
public class WayPoint : MonoBehaviour {
public WayPoint NextWayPoint;
}
2.控制玩家移動指令碼
public class PlayerMove : MonoBehaviour {
void Update () {
float h = Input.GetAxis ("Horizontal"); //x軸 ad
float v = Input.GetAxis ("Vertical");//z軸 ws
transform.Translate (h * Time.deltaTime * 2, 0, 0);
transform.Translate (0, 0, v * Time.deltaTime * 2);
}
}
3.敵人巡邏AI,發現玩家就追擊玩家,到一定距離攻擊
using UnityEngine;
using System.Collections;
/// <summary>
/// Enemy AI.
/// 敵人的AI,
/// 1. 3個點之間的巡邏
/// 2. 追擊,攻擊英雄
/// </summary>
public class EnemyAI : MonoBehaviour {
public WayPoint _startWayPoint;
WayPoint _targetWayPoint;
public GameObject _playerPoint;
GameObject _targetPoint;
void Start(){
_startWayPoint = GameObject.Find ("WayPoint1").GetComponent<WayPoint> ();
_playerPoint = GameObject.Find ("Player");
Vector3 v = _startWayPoint.transform.position;
// < 某值,根據實際值計算
if (Vector3.Distance (v, transform.position) < 0.5f) {
_targetWayPoint = _startWayPoint.NextWayPoint;
} else {
_targetWayPoint = _startWayPoint;
}
StartCoroutine (MyAI());
}
//第一種在Update裡,使用主程序來寫
/*
void Update(){
//巡邏前提->不用追擊英雄
Debug.Log("update...");
//判斷是否到達追擊的範圍
if (Vector3.Distance (transform.position, _playerPoint.transform.position) < 5) {
Debug.Log ("發現玩家...");
if (Vector3.Distance (transform.position, _playerPoint.transform.position) < 1) {
//播放攻擊動畫
Debug.Log ("攻擊動畫...");
} else {
//追擊
Debug.Log ("追擊中...");
_targetPoint = _playerPoint;
transform.LookAt (_targetPoint.transform);
transform.Translate (Vector3.forward * Time.deltaTime*2f, Space.Self);
}
} else {
//巡邏
Debug.Log ("巡邏中...");
Vector3 v = _targetWayPoint.transform.position;
if (Vector3.Distance (transform.position, v) < 0.5f) {
_targetWayPoint = _targetWayPoint.NextWayPoint;
Debug.Log("巡邏下一個點"+_targetWayPoint.name);
}
transform.LookAt (_targetWayPoint.transform.position);
transform.Translate (Vector3.forward * Time.deltaTime*2f, Space.Self);
}
}
*/
//以下使用協程來寫
//巡邏
IEnumerator MyAI(){
while (true) {
Vector3 v = _playerPoint.transform.position;
if (Vector3.Distance (transform.position, v) > 5f) {
Debug.Log ("巡邏中...");
Vector3 nextP = _targetWayPoint.transform.position;
if (Vector3.Distance (transform.position, nextP) < 0.5f) {
Debug.Log ("走下一個巡邏點");
_targetWayPoint = _targetWayPoint.NextWayPoint;
yield return new WaitForSeconds (1);
}
transform.LookAt (_targetWayPoint.transform);
transform.Translate (Vector3.forward * Time.deltaTime, Space.Self);
} else {
//Debug.Log ("發現玩家");
yield return StartCoroutine (MyNewAI ());
}
yield return new WaitForEndOfFrame ();
}
}
//追擊
IEnumerator MyNewAI(){
while (true) {
Vector3 PPos = _playerPoint.transform.position;
if (Vector3.Distance (transform.position, PPos) > 5) {
Debug.Log ("玩家超出追擊範圍,繼續巡邏...");
yield break;
} else {
if (Vector3.Distance (transform.position, PPos) < 1) {
Debug.Log ("攻擊中...");
} else {
Debug.Log ("追擊玩家...");
_targetPoint = _playerPoint;
transform.LookAt (_targetPoint.transform.position);
transform.Translate (Vector3.forward * Time.deltaTime, Space.Self);
}
}
yield return new WaitForEndOfFrame ();
}
}
}
總結
- 這個WayPoint路點尋路AI,其實一開始就一直在檢查、獲取玩家距離,
- 如果玩家玩家距離過大,就進行巡邏邏輯
- 當玩家進入設定的距離範圍時,則呼叫追擊、攻擊的邏輯