Exemple #1
0
    //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;
        }
    }
Exemple #2
0
    //进攻状态定时更新
    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);
    }
Exemple #3
0
 //同步数据函数
 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();
     }
 }
Exemple #4
0
    //相当于让守护者开始工作
    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;
    }
Exemple #5
0
    //空闲状态处理函数
    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);
        }
    }
Exemple #6
0
    //追踪状态处理函数
    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);
    }