I am implementing a state machine for game AI, and one of the states —EatState
— must be accessible from almost every other state and have priority over the rest. Instead of defining this transition in all the states, I was thinking of implementing it in a superclass BaseState
from which all the other extend.
BaseState
has 4 abstract methods that the subclasses override, which are
The problem I find if I implement the check for the transition to the EatState
in the superclass, and then call the particular checks of the subclass, is that the latter results override the ones obtained in the superclass:
public class BaseState {
public virtual void UpdateLogic() {
// Let's imagine the condition is met and the state is changed
if (someCondition){
changeState("EatState");
}
}
}
public class MoveState : BaseState {
public override void UpdateLogic() {
base.UpdateLogic();
// But here the condition is also met, so the state is re-changed.
if (someOtherCondition){
changeState("FightState");
}
}
}
I realise that I can just move the prioritary state check to the bottom of the method in order to override the result of the subclass:
public class MoveState : BaseState {
public override void UpdateLogic() {
if (someOtherCondition){
changeState("FightState");
}
base.UpdateLogic();
}
}
or that I could make the check in the subclass more restrictive, but this question kept me wondering about this:
Is there a way to avoid the execution of an override method once the base virtual method is being executed in the superclass? I am looking for something that would act like a return
statement that could somehow propagate from the superclass to the subclass and abort the latter execution.
You can control this behavior by returning bool instead of void to indicate if the base class behavior was used.
public class BaseState
{
public virtual bool UpdateLogic()
{
// Let's imagine the condition is met and the state is changed
if (someCondition)
{
changeState("EatState");
return true;
}
return false;
}
}
public class MoveState : BaseState
{
public override bool UpdateLogic()
{
var wasUpdatedInBase = base.UpdateLogic();
// But here the condition is also met, so the state is re-changed.
if (!wasUpdatedInBase && someOtherCondition)
{
changeState("FightState");
}
}
}