コード例 #1
0
    public override void BehaviourUpdate()
    {
        //Profiler.BeginSample("BehaviourUpdate");
        #region debug
        if (Input.GetKeyDown(KeyCode.B))
        {
            combat.Block(currentStance.blocks[0]);
        }
        if (Input.GetKeyDown(KeyCode.N))
        {
            combat.B_BlockFlinch();
        }
        if (Input.GetKeyDown(KeyCode.M))
        {
            combat.Evade(currentStance.evades[1]);
        }
        if (Input.GetKeyDown(KeyCode.L))
        {
            combat.MeleeAttack(null, currentStance.attacks[1]);
        }
        #endregion


        //cache some variables for later
        nearestEnemy        = sensing.nearestEnemy;
        currentStance       = unitAI.currentStance;
        myTransformPosition = entity.myTransform.position;
        enemyIsNull         = nearestEnemy == null;


        //1. look at the enemy, if no enemy present -> continue looking in the movement direction


        if (!enemyIsNull)
        {
            //but only if something chenged
            if (nearestEnemyLastFrame != nearestEnemy)
            {
                nearestEnemysTransform = nearestEnemy.myTransform;
                movement.LookAt(nearestEnemysTransform);
            }

            nearestEnemyPosition = nearestEnemysTransform.position;
            currentSquaredDistanceToNearestEnemy = (nearestEnemyPosition - myTransformPosition).sqrMagnitude;
        }
        else
        {
            if (nearestEnemyLastFrame != nearestEnemy)
            {
                movement.StopLookAt();
            }
        }

        switch (meleeAttackBehaviourState)
        {
        //2. if theres an enemy -> walk towards him
        case MeleeAttackBehaviourState.Idle:

            if (!enemyIsNull)
            {
                movement.MoveTo(nearestEnemyPosition);
                meleeAttackBehaviourState = MeleeAttackBehaviourState.MovingToNearestEnemy;
            }

            break;

        case MeleeAttackBehaviourState.MovingToNearestEnemy:

            //check if the enemy is still alive
            if (enemyIsNull)
            {
                meleeAttackBehaviourState = MeleeAttackBehaviourState.Idle;
                movement.Stop();
            }
            //else check if we reached the destination
            else if (currentSquaredDistanceToNearestEnemy < rangeToEnterMeleeCombatSquared)
            {
                meleeAttackBehaviourState = MeleeAttackBehaviourState.InMeleeFight;
            }
            //if not, check if we need to update the destination
            else
            {
                if (Time.time > nextUpdateDestinationTime)
                {
                    nextUpdateDestinationTime = Time.time + updateDestinationInterval;
                    movement.MoveTo(nearestEnemyPosition);
                }
            }

            break;

        case MeleeAttackBehaviourState.InMeleeFight:

            //check if the enemy is still alive
            if (enemyIsNull)
            {
                meleeAttackBehaviourState = MeleeAttackBehaviourState.Idle;
                movement.Stop();
            }
            //check if the enemy has not escaped
            else if (currentSquaredDistanceToNearestEnemy > rangeToEnterMeleeCombatSquared)
            {
                if (combat.currentCombatState == CombatState.CombatIdle)
                {
                    movement.MoveTo(nearestEnemyPosition);
                    meleeAttackBehaviourState = MeleeAttackBehaviourState.MovingToNearestEnemy;
                }
            }
            //else check if i am in range for an attack - fix range and attack
            else
            {
                //decision making .- thats the tricky part here
                if (combat.currentCombatState == CombatState.CombatIdle)
                {
                    //check if we should block because our adversary was faster
                    if (nearestEnemy.combat.currentCombatState == CombatState.PreparingMeleeAttack)
                    {
                        //if he is lucky he will block or evade, if not then not :D
                        if (Random.Range(0, 2) == 0)
                        {
                            if (Random.Range(0, 2) == 0)
                            {
                                combat.Block(currentStance.blocks[0]);
                            }
                            else
                            {
                                combat.Evade(currentStance.evades[0]);
                            }
                        }
                        else
                        {
                            combat.MeleeAttack(nearestEnemy, currentStance.attacks[Random.Range(0, currentStance.attacks.Length)]);
                        }
                    }
                    else
                    {
                        combat.MeleeAttack(nearestEnemy, currentStance.attacks[Random.Range(0, currentStance.attacks.Length)]);
                    }
                }
                else if (combat.currentCombatState == CombatState.Blocking)
                {
                    //check if we can stop blocking and attack
                    if (nearestEnemy.combat.currentCombatState != CombatState.PreparingMeleeAttack)
                    {
                        combat.MeleeAttack(nearestEnemy, currentStance.attacks[Random.Range(0, currentStance.attacks.Length)]);
                    }
                }
            }
            break;
        }

        nearestEnemyLastFrame = nearestEnemy;

        // Profiler.EndSample();
    }