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.
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;
}
}