我开始以为我哪里写错了 重新开了一个脚本 重新写了一遍 2个脚本一起看 发现重写的脚本声音判定依然没反应 坐标没有变化 我也查过声音判定的条件playerAnim.GetCurrentAnimatorStateInfo(0).IsName("Locomotion")是否名字写错,然后再Player脚本里面直接复制过来名字 也没有效果 还是判定没反应
截图在身后坐标没有变化 那个EnemySight1是重写一次代码 上面主角身上的动画器Animator 里面的Locomotion也在运。我在运动到机器人前面 视野判定没问题
我又检查了下机器人身上的导航模块也在啊
实在不知道为啥这个声音判定无法执行了
这个脚本的代码如下
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class EnemySight : MonoBehaviour {
//定义一个主角是否在视野内的状态 初始为否
public bool playerInSight = false;
//定义一个机器人前方的视野的角度
public float fieldOfView = 110;
//触发警报的坐标 声音和看到都要更新这个坐标
public Vector3 alertPosition = Vector3.zero;
//定义一个动画类 游戏动画
private Animator playerAnim;
//定义一个导航类的字段
private NavMeshAgent navAgent;
//定义一个球体碰撞器字段
private SphereCollider collider;
private void Awake()
{
//获取到主角身上的动画脚本
playerAnim= GameObject.FindGameObjectWithTag(Tags.player).GetComponent<Animator>();
//获取到这个导航组件
navAgent = this.GetComponent<NavMeshAgent>();
//获取这个球体碰撞器组件
collider = this.GetComponent<SphereCollider>();
}
/// <summary>
/// 这种方法都是实时监测的 触发停止的方法= =
/// </summary>
/// <param name="other"></param>
public void OnTriggerStay(Collider other)
{
if (other.tag == Tags.player)
{
//这个向量是是机器人的前方视野
Vector3 forward = transform.forward;
//这个向量是主角的视野方向 主角的位置 -敌人的位置 得到敌人到主角方向的向量
Vector3 playerDir = other.transform.position - transform.position;
//这个角度一定是正值
float temp= Vector3.Angle(forward, playerDir);
if (temp < 0.5f * fieldOfView)//如果这个角度小于视野角度的一半 代表在机器人视野内
{
playerInSight = true;
//警报位置为主角当前的坐标位置
alertPosition = other.transform.position;
//调用GameController脚本里面的SeePlayer方法
GameController._instance.SeePlayer(other.transform);
}
else//不在视野内
{
playerInSight = false;
}
//下面的是声音判断方法 上面的是视角判断方法
//判断当前状态名字是不是这个名字 如果是代表这个名字的动画是播放状态 则有脚步声 在Player脚本里面 我们写了这个方法
if (playerAnim.GetCurrentAnimatorStateInfo(0).IsName("Locomotion"))
{
//创建一个新的导航类 路径变量
NavMeshPath path = new NavMeshPath();
//在导航组件里面有一个计算路径的方法 传进去 目标位置 和导航路径
if (navAgent.CalculatePath(other.transform.position, path))
{
//路径点 是由一堆导航方格组成的也可以说是一堆点组成 path.corners.Length表示记录的路线的点的数组的长度,
//+2表示 机器人的位置算一个 主角的位置算一个 如果不懂 请重看秘密行动30 20分钟
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++)
{
//通过后一个坐标的点的坐标 -前一个坐标点的坐标 得到一个向量 在通过magnitude这个大小方法得到这个向量的长度
//其实就是比如第一次运行的时候i是0 第二次运行的时候i是2 这个就得到0点到2点之间的长度
//然后在不断累加 得到的就是路径的长度
length += (wayPoints[i] - wayPoints[i - 1]).magnitude;
}
//collider.radius是外面球体碰撞器上面的一个触发范围选项的大小
//如果成立代表声音在当前触发判断范围内
if (length < collider.radius)
{
//将警报位置 改为主角当前的坐标位置
alertPosition = other.transform.position;
}
}
}
}//if (other.tag == Tags.player)
}// public void OnTriggerStay(Collider other)
/// <summary>
/// 触发开始的方法
/// </summary>
/// <param name="other"></param>
public void OnTriggerExit(Collider other)//这个方法是主角不在视野内触发的方法? 我咋看不懂
//看懂了 这个方法是在他的那个触发圈圈内 但是没有在视野内的方法
{
if (other.tag == Tags.player)
{
playerInSight = false;
}
}
}
问题我解决了 我把场景的静态化给关了 不过我现在又出现一个新的问题 就是32集的机器人在4个坐标巡逻 我的代码一模一样的写 那机器人不动 我用print(index)查看方法运行状态 发现控制台只运行了一次巡逻方法
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class EnemyMoveAI : MonoBehaviour {
//定义一个组件 用来存巡逻坐标
public Transform[] wayPoints;
//定义一个巡逻休息的时间 默认为3秒
public float patrolTime = 3f;
private float patrolTimer = 0;
private int index = 0;
//定义一个导航字段
private NavMeshAgent navAgent;
private void Awake()
{
//获取到这个导航组件
navAgent = this.GetComponent<NavMeshAgent>();
//导航的目标位置=巡逻坐标数组里面的其中一个坐标
navAgent.destination = wayPoints[index].position;
}
void Update()
{
//调用巡逻方法
Patrolling();
}
/// <summary>
/// 巡逻方法
/// </summary>
private void Patrolling()
{
//remainingDistance是剩余多少距离的方法
//如果这个navAgent还剩的距离还差、小于0.5,我们就默认它到达了目标位置
if (navAgent.remainingDistance < 0.5f){
//关闭导航
navAgent.Stop();
//开始计时计算休息时间
patrolTimer += Time.deltaTime;
//休息时间已经到了
if (patrolTimer > patrolTime)
{
index++;
//index=index%4
// %是取余运算符,当要处理 X % Y时, 如果, X < Y 的话, 回传值就是 X 自己 当index等4时 就归零
index %= 4;
navAgent.destination = wayPoints[index].position;
//休息计时器重新归零
patrolTimer = 0;
print(index);
}
}
}
}