Skip to content

Add Grounded marker for KinematicCharacterController #504

@Jondolf

Description

@Jondolf

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.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions