Input Buffer
The Input System offers an Input Buffer that allows deferring the execution of Input Handlers to a later moment.
This is particularly useful in combat systems where players might press keys during animations that cannot be interrupted, yet the game should still register these inputs to ensure responsiveness.
Input Buffer Design
The buffer is implemented using the Command design pattern: Inputs that cannot be handled immediately are encapsulated in a Command structure, which can be executed later when the buffer is closed.
The Input Buffer is Animation-Based, meaning it is opened and closed at specific points during an animation, controlled through an Animation Notify State.
Although the Input Manager Component manages the buffer by default, the Input Buffer functionality is defined by the InputBufferInterface
. Any component that implements this interface can be engaged by the animation, provided it is enabled.
You can also disable the Input Manager's buffer if you wish to replace it with your own custom Buffer Component, making the system highly flexible.
Using the Input Buffer
To buffer actions, follow these steps:
Enable the
Can Be Buffered
property on any Input Handlers you wish to add to the Input Buffer.Add the Notify State to an animation that supports buffering inputs.
Enabling Input Handlers for Buffering
To allow an Input Handler to be buffered, enable its Can Be Buffered
property when registering the Input Handler to a UNinjaInputSetupDataAsset
.
Opening and Closing the Input Buffer in Animations
The most straightforward way to open and close the Input Buffer is by using the Input Buffer Animation Notify State.
Once the state Begins, the Input Buffer will open, and the Input Manager Component will stop routing Input Actions to Handlers. Instead, it will store any handlers that would have been triggered, along with their current Input Action Values, based on the buffering policy in place.
Once the state Ends, the Input Buffer will close, and any stored Input Handlers related to a saved Action will be invoked using the previously saved values.
Externally Opening and Closing the Buffer
While the method above is the primary way to interact with the Buffer, you can open and close the buffer in other ways using the InputBufferInterface
.
Default Input Buffer Implementation
The UNinjaInputBufferComponent
is the default implementation of the InputBufferInterface
and provides an additional feature: the Buffering Policy.
There are three possible values for this policy:
Last Command: All Input Actions will be processed until the buffer is closed. When that happens, the last Action processed will be the one executed. This is the default mode.
First Command: Once the first valid Input Action is saved, no other Actions will be kept, and this first Action will be the one executed.
Disabled: Disables the Ninja Input Buffer and allows another custom buffer to take over.
Creating New Input Buffers
You can create your own Input Buffer by creating an Actor Component that implements the InputBufferInterface
.
If you choose this route, ensure that the Input Manager Component's Buffer is disabled and that your custom component is enabled using the appropriate interface method.
Another option is to create your component as a subclass of the NinjaInputBufferComponent
, which already implements the necessary interface and provides additional utility methods.
This approach allows you to implement only the functions relevant to your scenario, such as BufferInputCommands
, which decides if a command should be buffered.
The FBufferedInputCommand Struct
Commands stored in the buffer are represented by the FBufferedInputCommand
struct.
The main Input Manager Component creates these instances when input handlers are routed to the buffer instead of being processed immediately. The BufferInputCommands
function receives an array of commands because all the commands in that array were triggered by the same Action and Event, so they represent a single player input.