Behavior

Behavior

START
1
GET READY TO RUMBLE
  • 6.1.1 Create a new melee attack that darts forward to hit the player and returns back
  • 6.1.2 Create a new melee enemy using FSM or Priority behaviors that uses that attack
  • 6.1.3 After each attack, the enemy retreats briefly in a random direction (away from player)

Create another enemy and explore the behavioral system. You can copy either of the two examples given in the project for Enemy1. This new enemy has no extra actions or animations, for simplicity.

If you copy Target.cs, you'll be creating additional IBehavior classes in the Behaviors directory. TargetFSM.cs is entirely self-contained.

I mentioned in class as were critiquing the AI-generated code that the assistant had replaced the traditional FSM GetNextState with a global priority approach in TargetFSM. At the bottom of this panel is what the traditional FSM GetNextState would look like. You now have three state management examples: (traditional FSM state transitions below, priority checks with conditions in TargetFSM.cs, and a straight up priority list in Target.cs). Regardless of which of those you use, you can combine it with separating out IBehavior classes or not.

  • Copy either Target.cs or TargerFSM.cs and rename the file and the main class inside
  • Attach the new script to Enemy2 in the scene
  • Get rid of things you don't need (e.g. the boomerang action) and update its behavior to:
    • Move directly towards the player
    • When it gets close enough, do a short (1 unit) dash towards the player and then back
    • After attacking, back off in a random direction for a second
    • Repeat
  • Make sure your new attack applies damage to the player
  • The player slash should interrupt your attack with its knockback effect that's already in place
private EnemyState GetNextState(float distanceToPlayer)
{
    bool attackOffCooldown = boomerangCooldownTimer <= 0f;
    bool inAttackRange = distanceToPlayer <= boomerangRange;
    
    switch (currentState)
    {
        case EnemyState.Attack:
            // If in the middle of attacking, keep going
            if (isBoomerangAttacking)
                return EnemyState.Attack;
            
            // Attack is done - decide next state based on conditions
            // If attack is off cooldown and in range, attack again
            if (attackOffCooldown && inAttackRange)
                return EnemyState.Attack;
            
            // If attack is off cooldown but out of range, close distance
            if (attackOffCooldown && !inAttackRange)
                return EnemyState.Close;
            
            // If on cooldown, kite around
            return EnemyState.Kite;

        case EnemyState.Close:
            // If we get in range and attack is ready, switch to attack
            if (attackOffCooldown && inAttackRange)
                return EnemyState.Attack;
            
            // If attack goes on cooldown while closing, switch to kiting
            if (!attackOffCooldown)
                return EnemyState.Kite;
            
            // Otherwise keep closing
            return EnemyState.Close;

        case EnemyState.Kite:
            // If attack comes off cooldown and we're in range, attack
            if (attackOffCooldown && inAttackRange)
                return EnemyState.Attack;
            
            // If attack comes off cooldown but we're out of range, close
            if (attackOffCooldown && !inAttackRange)
                return EnemyState.Close;
            
            // Otherwise keep kiting
            return EnemyState.Kite;

        default:
            return currentState;
    }
}
Save Point
SAVE POINT
commit your work