/// <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);
        }
    }
Esempio n. 2
0
    /// <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;
                }
            }
        }
    }