//guard状态机更新函数 void FSMUpdate() { //根据guard当前的状态调用相应的状态处理函数 switch (currentState) { case GuardFSMState.Idle: UpdateIdleState(); break; case GuardFSMState.Chase: UpdateChaseState(); break; case GuardFSMState.Attack: UpdateAttackState(); break; case GuardFSMState.Dead: UpdateDeadState(); break; } //如果guard处于非死亡状态,但是生命值减为0,那么进入死亡状态 if (currentState != GuardFSMState.Dead && !guardHealth.IsAlive) { currentState = GuardFSMState.Dead; } }
//进攻状态定时更新 void UpdateAttackState() { //如果guard感知范围内没有玩家,进入游荡状态 targetPlayer = guardSensor.getNearbyPlayer(); if (targetPlayer == null) { currentState = GuardFSMState.Idle; agent.ResetPath(); animator.SetBool("isAttack", false); return; } //如果玩家与guard的距离,大于guard的攻击距离,那么进入追踪状态 if (Vector3.Distance(targetPlayer.position, guardTransform.position) > attackRange) { currentState = GuardFSMState.Chase; agent.ResetPath(); animator.SetBool("isAttack", false); return; } PlayerHealth ph = targetPlayer.GetComponent <PlayerHealth> (); if (ph != null) { //计算guard的正前方和玩家的夹角,只有玩家在guard前方才能攻击 Vector3 direction = targetPlayer.position - guardTransform.position; float degree = Vector3.Angle(direction, guardTransform.forward); if (degree < attackFieldOfView / 2 && degree > -attackFieldOfView / 2) { animator.SetBool("isAttack", true); if (attackTimer > attackInterval) { attackTimer = 0; if (attackAudio != null) { photonView.RPC("PlayAttackAudio", PhotonTargets.All); } ph.TakeDamageFromZombie(attackDamage); } attackTimer += Time.deltaTime; } else { //如果玩家不在guard前方,guard需要转向后才能攻击 animator.SetBool("isAttack", false); guardTransform.LookAt(targetPlayer); } } //攻击状态下的敌人应当连续追踪玩家 agent.SetDestination(targetPlayer.position); //限制追踪的速度 setMaxAgentSpeed(runSpeed); }
//同步数据函数 void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info) { if (stream.isWriting) //本地玩家发送数据 { stream.SendNext(currentState); //同步当前状态 是否第一次进入死亡状态 和动画机的rootMotion标记 stream.SendNext(firstInDead); stream.SendNext(animator.applyRootMotion); } else //远程玩家接收数据 { currentState = (GuardFSMState)stream.ReceiveNext(); firstInDead = (bool)stream.ReceiveNext(); animator.applyRootMotion = (bool)stream.ReceiveNext(); } }
//相当于让守护者开始工作 public void Born() { //把guard感知到的玩家字段设置为null血量 targetPlayer = null; //把guard的初始化状态设置为游荡状态, currentState = GuardFSMState.Idle; //初始化guard生命值 guardHealth.currentHP = guardHealth.maxHP; //启用导航代理组件 EnableGuard(true); if (PhotonNetwork.isMasterClient) { agent.ResetPath(); } //启用动画控制器 animator.applyRootMotion = false; firstInDead = true; }
//空闲状态处理函数 void UpdateIdleState() { targetPlayer = guardSensor.getNearbyPlayer(); if (targetPlayer != null) { currentState = GuardFSMState.Chase; agent.ResetPath(); animator.SetBool("isAttack", false); return; } //设置移动目标为守护原点 agent.SetDestination(SourcePointTransform.position); if (AgentDone()) //回到了守护原点 { setMaxAgentSpeed(0); } else { setMaxAgentSpeed(runSpeed); } }
//追踪状态处理函数 void UpdateChaseState() { //如果guard感知范围内没有玩家,进入游荡状态 targetPlayer = guardSensor.getNearbyPlayer(); if (targetPlayer == null) { currentState = GuardFSMState.Idle; agent.ResetPath(); return; } //如果玩家与guard的距离,小于guard的攻击距离,那么进入攻击状态 if (Vector3.Distance(targetPlayer.position, guardTransform.position) <= attackRange) { currentState = GuardFSMState.Attack; agent.ResetPath(); return; } //设置移动目标为玩家 agent.SetDestination(targetPlayer.position); //限制追踪的速度 setMaxAgentSpeed(runSpeed); }