/// <summary> /// 有限状态机状态轮询时调用。 /// </summary> /// <param name="fsm">有限状态机引用。</param> /// <param name="elapseSeconds">逻辑流逝时间,以秒为单位。</param> /// <param name="realElapseSeconds">真实流逝时间,以秒为单位。</param> protected override void OnUpdate(IFsm <Monster> fsm, float elapseSeconds, float realElapseSeconds) { base.OnUpdate(fsm, elapseSeconds, realElapseSeconds); if (fsm.Owner.IsLockingAim) { FightEntity aim = fsm.Owner.LockingAim; if (aim != null && aim.IsDead == false) { fsm.Owner.transform.LookAt(aim.transform); // 除非敌人离开了自己的攻击范围,否则,在锁定目标的过程中,不进行移动(避免不断和敌人靠近,直至重合) float distance = AIUtility.GetDistance(fsm.Owner, aim); if (fsm.Owner.CheckInAtkRange(distance) == false) { fsm.Owner.Forward(elapseSeconds); } return; } } if (fsm.Owner.MoveController == null) { return; } Vector3 inputVec = fsm.Owner.MoveController.GetInput(); if (inputVec.y != 0) { // 移动 fsm.Owner.Forward(inputVec.y * elapseSeconds); } else { // 站立 ChangeState <MonsterIdleState> (fsm); } }
/// <summary> /// 有限状态机状态轮询时调用。 /// </summary> /// <param name="fsm">有限状态机引用。</param> /// <param name="elapseSeconds">逻辑流逝时间,以秒为单位。</param> /// <param name="realElapseSeconds">真实流逝时间,以秒为单位。</param> protected override void OnUpdate(IFsm <Monster> fsm, float elapseSeconds, float realElapseSeconds) { base.OnUpdate(fsm, elapseSeconds, realElapseSeconds); if (fsm.Owner.IsAtkCDing || GlobalGame.IsPause) { return; } if (fsm.Owner.IsLockingAim) { FightEntity aim = fsm.Owner.LockingAim; if (aim == null || aim.IsDead) { ChangeState <MonsterIdleState>(fsm); return; } float distance = AIUtility.GetDistance(fsm.Owner, aim); /* 进入攻击范围,直接攻击 */ if (fsm.Owner.CheckInAtkRange(distance)) { fsm.SetData <VarInt> (Constant.EntityData.LockAimID, aim.Entity.Id); ChangeState <MonsterAtkState> (fsm); } /* 在视线范围内,则继续移动 */ else if (fsm.Owner.CheckInSeekRange(distance)) { if (fsm.CurrentState.GetType() != typeof(MonsterWalkState)) { ChangeState <MonsterWalkState>(fsm); } } else { fsm.Owner.UnlockAim(); } return; } /* 判断是否有敌人进入追踪或攻击范围 */ CampType camp = fsm.Owner.GetImpactData().Camp; GameObject[] aims = GameObject.FindGameObjectsWithTag("Creature"); foreach (GameObject obj in aims) { FightEntity aim = obj.GetComponent <FightEntity> (); if (aim.IsDead == false && AIUtility.GetRelation(aim.GetImpactData().Camp, camp) == RelationType.Hostile) { float distance = AIUtility.GetDistance(fsm.Owner, aim); /* 进入攻击范围,直接攻击 */ if (fsm.Owner.CheckInAtkRange(distance)) { fsm.SetData <VarInt> (Constant.EntityData.LockAimID, aim.Entity.Id); ChangeState <MonsterAtkState> (fsm); break; } /* 进入追踪范围,向目标移动 */ else if (fsm.Owner.CheckInSeekRange(distance)) { fsm.Owner.LockAim(aim); ChangeState <MonsterWalkState>(fsm); break; } } } }