今天开始记录自己游戏开发的过程,算是自己的一个笔记吧。
首先让敌人追寻玩家的方法有三种。
第一种,玩家出现在敌人的视野内
简单的来说,就是当敌人“看见”玩家的时候(玩家出现在敌人的视野内),让敌人开始靠近玩家。
这种情况得先在敌人身上绑定一个摄像机,然后当摄像机内出现玩家,且出现的范围比较大的时候,让敌人开始追寻玩家。
(具体在unity中的体现,α为摄像机与玩家之间的夹角)
当α角大于摄像机视野角的一半的时候,就认为敌人看到了玩家,并且进行追寻。
第二种,玩家的声音被敌人所“听到”
这种我在unity中不好表示出来,我画图出来表示
第三种,玩家进入敌人的圆形侦测范围内
给敌人身上挂一个shere,然后取消掉Mesh Renderer组件,在OnTriggerEnter(Collider other)函数内进行判断和让敌人进行追寻
具体的实现代码片段如下
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 SphereCollidersphereCollider;//敌人身上的碰撞器,该碰撞器是用来触发检测主角是否在敌人可见,可听范围内
private NavMeshAgentnavMeshAgent; //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 (inti = 0; i<path.corners.Length; i++)
{
wayPoints[i + 1] = path.corners[i];
}
float length = 0;
for (inti = 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;
}
}
上面是前两种“看”和“听”所实现的代码
下面是实现进入到侦测范围的实现方法,部分内容与上面代码相似,这里仅显示思路和部分代码片段。
private void OnTriggerEnter(Collider other){
if(other.tag == "Tag.Player")
{
//看玩家
Vector3 startDir = transform.forward;//敌人开始朝向
isSeePlay = true;
alermPos = other.transform.position;//把玩家的位置设置为警报位置
GameController._instance.SeePlayer(other.transform);
}
else
{
isSeePlay = false;
}
}
最后,如果感兴趣的话,还可以加入我的技术交流小窝:1140238314
转载:https://blog.csdn.net/qq_39750907/article/details/116074283
查看评论