1. 程式人生 > >unity_實用小技巧(敵人追蹤主角)

unity_實用小技巧(敵人追蹤主角)

ren 聽力 5* iss 發現 date() ima nav path

首先要明白敵人發現主角可以通過兩種形式:一種是見主角(即主角出現在敵人的視野之內)。另一種是見主角(即聽見主角走路聲或者是跑步聲)

第一種形式:看。

如下圖 ,判斷主角是否在敵人視野角度內,只需判斷B<0.5*A是否成立

技術分享

第二種形式,聽。

技術分享

using UnityEngine;
using System.Collections;
using UnityEngine.AI;

public class EnemySight : MonoBehaviour {

private float seeAngle=120;//敵人視野角度
private bool isSeePlay = false;

private Vector3 lastPos;// 玩家的最後位置
private Vector3 alermPos=Vector3.zero; //警報位置

private Animator anim; //主角動畫,作用是判斷主角是否在運動
private SphereCollider sphereCollider;//敵人身上的碰撞器,該碰撞器是用來觸發檢測主角是否在敵人可見,可聽範圍內
private NavMeshAgent navMeshAgent; //AI組件

void Awake()
{
anim = GameObject.FindGameObjectWithTag(Tags.player).GetComponent<Animator>();
lastPos = GameController._instance.lastPlayerPostion;
navMeshAgent = GetComponent<NavMeshAgent>();
}

void Update()
{
//同步主角位置
if (lastPos != GameController._instance.lastPlayerPostion)//觸發警報後玩家位置改變
{
alermPos = GameController._instance.lastPlayerPostion; //更新警報位置
lastPos = GameController._instance.lastPlayerPostion;
}

}

void OnTriggleStay(Collider other)
{
if (other.tag==Tags.player)
{
//看玩家
Vector3 startDir = transform.forward;//敵人開始朝向
Vector3 currDir = other.transform.position - transform.position; //敵人看向玩家的向量
float angle = Vector3.Angle(startDir, currDir);//敵人開始朝向與看見玩家朝向的夾角
if (angle < seeAngle * 0.5f) //視野角度一半以內可見
{
//主角在敵人的視野之內
isSeePlay = true;
alermPos = other.transform.position;//把玩家的位置設置為警報位置
GameController._instance.SeePlayer(other.transform);
}
else
{
isSeePlay = false;
}


//聽腳步聲音
if (anim.GetCurrentAnimatorStateInfo(0).IsName("Locomotion"))//如果玩家在運動
{
NavMeshPath path = new NavMeshPath();
if (navMeshAgent.CalculatePath(other.transform.position, path))
{
Vector3[] wayPoints = new Vector3[path.corners.Length+2];
wayPoints[0] = transform.position;
wayPoints[wayPoints.Length - 1] = other.transform.position;
for (int i = 0; i < path.corners.Length; i++)
{
wayPoints[i + 1] = path.corners[i];
}
float length = 0;
for (int i = 1; i < wayPoints.Length; i++)
{
length += (wayPoints[i] - wayPoints[i - 1]).magnitude; //所有節點連接的折線的總長度
}
if (length <= sphereCollider.radius) //在聽力範圍內
{
alermPos = other.transform.position;
}
}
}

}
}

void OnTriggleExit(Collider other)
{
if (other.tag == Tags.player)
{
isSeePlay = false;
}
}

unity_實用小技巧(敵人追蹤主角)