For Enemy AI State Machine In Game Design, Should the State Itself Evaluate Logic to Transition to Next State?

163 Views Asked by At

I am building an Enemy AI State Machine, Where I have these scripts.

Setup

  • Enemy
  • EnemyStateManager
  • EnemyStateBase

States

  • InitialState
  • RoamingState
  • PursuingState
  • AttackingState
  • RetreatingState

When I am inside of an enemy state, for example, let's say Pursuing State, where the enemy's role is to chase the target until its within attack range. I am not sure if I should be programming the decision-making process of the enemy inside the state, or have a separate script that will call actions on the current state, and the state relaying whether that action is possible within the state.

Currently, the EnemyStateManager is set up like this.

public class StateMachine : MonoBehaviour {

    private EnemyStateBase _currentState;
    private Enemy _enemy;

    public Enemy Enemy { get => _enemy; set => _enemy = value; }


    private void Start() {
        _currentState = new RoamingState(this);
    }

    public void ChangeState(State newState) {
        _currentState.ExitState();
        _currentState = newState;
        _currentState.EnterState();
    }
    
    public void Update(){
        _currentState.UpdateState();
    }


}

Example of Question

Below you see that I am in Pursuing State and checking to see on Update if I am within attack range. It feels weird to try to evaluate AI Logic inside the state, but if this seems like a common practice and follows coding guidelines then I guess I'm worried for nothing.

public class PursuingState : EnemyStateBase {

    private EnemyStateManager _esm;

    public PursuingState (EnemyStateManager esm){
        _esm = esm;
}
    public override void EnterState() {
        // Do something when entering the pursuing state
    }

    public override void UpdateState() {
        // Check To See If you Entered Attack Range with target
        var targetPos = _esm.Enemy.Target.Transform.Position;
        var myPos = _esm.Enemy.Transform.Position;

        if(Vector3.Difference(mypos, targetpos) < _esm.Enemy.AttackRange){
            _esm.ChangeState(new AttackState(_esm));
        }

    }

    public override void ExitState() {
        // Do something when exiting the pursuing state
    }

Non-AI Situation

If I were to build a state machine that was from player input then the player is the decision maker, and the input is relayed to the state machine, and the state machine will respond with appropriate action based on my input.

Summary

The Enemy AI example seems like AI input comes from within the state itself, whereas in a traditional setup with player input, it comes from outside the state machines. Is the Enemy AI example seem like a typical example?

1

There are 1 best solutions below

0
Renan Ruan On

Yes, it is! Do you know about Design Patterns? They're commum designed solutions of commum problems that you find whe designing a software. This example shows the State Pattern, used to control the state of a class during runtime and create cohesive state machines.

Here is a link if you want to know more about it.