Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sometimes CollidingEntities will accumulate all the collided entities, sometimes not #161

Closed
rewin123 opened this issue Sep 27, 2023 · 2 comments · Fixed by #112
Closed
Labels
A-Collision Relates to the broad phase, narrow phase, colliders, or other collision functionality C-Bug Something isn't working

Comments

@rewin123
Copy link

rewin123 commented Sep 27, 2023

image

Sometimes CollidingEntities starts behaving incorrectly. Sometimes after the end of a collision with an object, its entity is not removed from the list, resulting in a hang in the air for the player's dynamic controller, as shown below. In case the incorrect behavior of the component has started, it starts accumulating in CollidingEntities all entities it has encountered. Sometimes incorrect behavior is not observed.

Cube controller code:

app.add_systems(PhysicsSchedule, move_player.run_if(in_state(EditorState::Game)).before(PhysicsStepSet::BroadPhase))

...

fn move_player(
    keyboard_input: Res<Input<KeyCode>>,
    mut query: Query<(Entity, &mut LinearVelocity, &mut AngularVelocity, &PlayerController, &CollidingEntities, &mut Transform)>,
    time : Res<Time>
) {
    for (e, mut vel, mut rot, controller, colliding, tranform) in query.iter_mut() {
        if colliding.len() > 0 {
            info!("colliding: {:?}", colliding);
            
            let frw = tranform.forward();
            let up = tranform.up();

            let mut target_vel = Vector::new(0.0, 0.0, 0.0);
            if keyboard_input.pressed(KeyCode::W) {
                target_vel += frw;
            }
            if keyboard_input.pressed(KeyCode::S) {
                target_vel -= frw;
            }
            //rotate
            if keyboard_input.pressed(KeyCode::A) {
                rot.y = 2.0;
            } 
            if keyboard_input.pressed(KeyCode::D) {
                rot.y = -2.0;
            }
            if !keyboard_input.pressed(KeyCode::A) && !keyboard_input.pressed(KeyCode::D) {
                rot.y -= 10.0 * rot.y * time.delta_seconds();
            }
            
            target_vel *= controller.speed;

            if keyboard_input.pressed(KeyCode::Space) {
                target_vel += up * controller.jump_speed;
            }

            //smooth change vel
            let cur_vel = vel.0.clone();
            let cur_vel = vel.0 + (target_vel - cur_vel) * 10.0 * time.delta_seconds();
            vel.0 = cur_vel;

        } else {

        }
    }    
}

Full code can be founded at https://github.com/rewin123/space_editor/blob/v0.1/examples/platformer.rs

Tested on 8b2ea8f in main branch

@rewin123 rewin123 changed the title Sometimes CollidingEntities will accumulate all the entities encountered, sometimes not Sometimes CollidingEntities will accumulate all the collided entities, sometimes not Sep 27, 2023
@Jondolf Jondolf added C-Bug Something isn't working A-Collision Relates to the broad phase, narrow phase, colliders, or other collision functionality labels Sep 27, 2023
@Jondolf Jondolf linked a pull request Sep 27, 2023 that will close this issue
@Jondolf
Copy link
Owner

Jondolf commented Oct 14, 2023

Hi, I finally finished up the work for #112. I tested your example and it now seems to be updating CollidingEntities correctly.

Cool project btw! Looks very useful :)

Jondolf added a commit that referenced this issue Oct 14, 2023
# Objective

Fixes #161.

There are currently several issues with how collision events, `CollidingEntities` and sleeping are handled.

- Removing a collider from underneath a sleeping body will leave that body floating in the air, because from the engine's perspective, the bodies aren't penetrating.
- When a body is marked as sleeping, all of its collisions are discarded, and the `CollisionEnded` event is sent despite the bodies still being in contact from the user's perspective.
- Collision events are being sent only if the bodies are penetrating during the last substep during a physics frame, which is often not the case, because most collisions should be solved by then. This can lead to missed collision events and issues with `CollidingEntities` not being updated.

## Solution

This PR aims to fix all of these issues listed above.

Collision events are handled in a much more robust way. `Contacts` has `during_current_frame`, `during_current_substep` and `during_previous_frame` properties that are used to track when to send each type of collision event or update `CollidingEntities`. This also lets us remove `PreviousCollisions`.

Collisions against sleeping bodies are also handled better. When a collision against a sleeping body ends (through movement or despawn), the bodies are woken up. Collisions between bodies are also not discarded when they start sleeping.
@rewin123
Copy link
Author

Thanks for the fix. xpbd project is also very useful, could be said a small revolution for bevy:)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Collision Relates to the broad phase, narrow phase, colliders, or other collision functionality C-Bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants