Rather than simply attempting a state change and giving up if it isn't allowed, it is often desirable to keep trying for a short time. For example, if the player is attacking and they press the attack button again, you probably want the current animation to finish first and then start the next attack in a combo as long as the input didn't occur too long ago. Note that "input" in this case does not only mean "button presses from the player", it can be used for any sort of events that might try to control a state machine (such as AI).
The StateMachine<TState>.InputBuffer
class allows you to easily implement this sort of buffering:
- Construct a
new StateMachine<TState>.InputBuffer
by passing in the target state machine. - Whenever you would normally call
TryResetState(state)
on the state machine, you can instead callBuffer(state, timeOut)
on the input buffer which will make it callTryResetState
and if it fails, then it will store thestate
to try again later. - Call
Update
on the buffer every frame to have it try to enter the buffered state again (if there is one).
The Weapons example demonstrates how to use this system.
This system only buffers a single state at a time. If the player presses the attack button while they are already attacking then presses the block button before the first attack ends, it will only execute the block rather than performing the entire second attack before blocking. This assumes the latest command is the only one that matters, which is often good for things like player input, but might not be best for all situations. If you want to ensure that all commands are executed in order, you could make a similar class (perhaps called InputSequenceBuffer
) which manages a list of states instead of only a single BufferedState
.