Add `Grounded` marker for `KinematicCharacterController`
A pretty common question I see people ask is "how do I know if my character is grounded?"
This is currently done by querying for the KinematicCharacterControllerOutput component and checking the is_grounded property.
fn log_grounded(controllers: Query<(Entity, &KinematicCharacterControllerOutput)>) {
for (entity, output) in &controllers {
println!("Entity {:?} touches the ground: {:?}", entity, output.grounded);
}
}
However, in my opinion, a more idiomatic approach would be a Grounded marker component. Paired with the Without filter, it would make some systems more ergonomic while also reducing the amount of iteration. For example, a simple jumping system could filter out entities that aren't grounded:
fn jump(
mut jump_event_reader: EventReader<JumpEvent>,
mut controllers: Query<&mut Velocity, With<Grounded>>,
) {
for event in jump_event_reader.read() {
for (jump_impulse, mut velocity) in &mut controllers {
// A KCC isn't controlled like this, but imagine it works for demonstration purposes.
velocity.linvel.y = event.jump_impulse;
}
}
}
For the boolean value, the idiomatic approach is to use Has:
fn log_grounded(controllers: Query<(Entity, Has<Grounded>)>) {
for (entity, is_grounded) in &controllers {
println!("Entity {:?} touches the ground: {:?}", entity, is_grounded);
}
}
If desired, the name could also be more specific like CharacterGrounded or even KinematicCharacterGrounded, but I think just Grounded is fine too.
The grounded field of KinematicCharacterControllerOuptput is not very useful on its own, as it fluctuates a lot even when the character is not moving.
For example, the character_controller3 example uses a timer to consider a character grounded and avoid missing jump inputs
so having it as a marker component in fact be great, but it would require some options to define what is grounded or not, like with a time threshold, or frame average, etc