Expand description
Module to handle client inputs
Client inputs are generated by the user and sent to the server. They have to be handled separately from other messages, for several reasons:
- the history of inputs might need to be saved on the client to perform rollback and client-prediction
- we not only send the input for tick T, but we also include the inputs for the last N ticks before T. This redundancy helps ensure that the server isn’t missing any client inputs even if a packet gets lost
- we must provide
SystemSet
s so that the user can order their systems before and after the input handling
§Adding a new input type
An input type must be serializable, Reflect
, MapEntities
, Clone
, PartialEq
, and Debug
.
You can then add the input type by adding the InputPlugin<InputType>
to your app.
use lightyear_inputs_native::prelude::*;
#[derive(Serialize, Deserialize, Clone, PartialEq, Reflect, Debug)]
pub enum MyInput {
Move { x: f32, y: f32 },
Jump,
// we need a variant for "no input", to differentiate between "no input" and "missing input packet"
None,
}
// every input must implement MapEntities
impl MapEntities for MyInput {
fn map_entities<M: EntityMapper>(&mut self, entity_mapper: &mut M) {
}
}
let mut app = App::new();
app.add_plugins(InputPlugin::<MyInput>::default());
§Sending inputs
There are several steps to use the InputPlugin
:
- (optional) read the inputs from an external signal (mouse click or keyboard press, for instance)
- to buffer inputs for each tick. This is done by setting the input value in the
ActionState
component. That system must run in theWriteClientInputs
system set, in theFixedPreUpdate
stage. - handle inputs in your game logic in systems that run in the
FixedUpdate
schedule. These systems will read the inputs using theActionState
component