Closed sebcrozet closed 4 years ago
The character controller use case depends on whether it makes sense for a character controller to be a kinematic body rather than a sensor or a procedure that runs queries each step and doesn't actually exist in the physics world per se. A kinematic body makes it easy to exert forces on the environment, which is useful in theory, but seems liable to produce instability in practice.
Kinematic and static don't generate collision events? Aw man i'm trying to make a character controller right now and rapier just keeps surprising me with very ..... unique design decisions. I can't seem to find any examples of a good kinematic controller implementation anywhere. Was originally going to use dynamic for my controller, but that proved to be majorly jank with the tools I could find available to me.
How then if not with collision detection should i stop my controller from falling through floors and walking through walls? I assume the standard ray/box cast method should be used?
If anyone knows of any good examples for either dynamic or kinematic character controllers in bevy I would love to see them :D for now i guess it is time to put on my linear algebra hat
For me for Cand.li that would be extremely useful. Currently I'm using Planck-JS that ignores these contacts as well and it is a big limitation as it prevents the detection of a platform reaching the end of a gap for example.
So indeed for my specific use case it would be helpful that such contacts are detected but not used in the constraint solver.
Also theoretically, personally I would find it nice that the contact detection, which is a geometry operation, is independent of the actual physics. Of course I can imagine that for performance reason some pruning should rather be done early, so it might be best to have it as a global option, or per body or collider/sensor.
@ConnorBP
Kinematic and static don't generate collision events? Aw man I'm trying to make a character controller right now and rapier just keeps surprising me with very ..... unique design decisions.
Kinematic/static contacts are ignored by most physics engines out there. Keep in mind that what you call design decisions are either missing features, or decisions that are still open to discussion (including what this issue is about). So if you find something missing or some design decisions bothering you, don't hesitate to open issues to see what we can do about it.
How then if not with collision detection should i stop my controller from falling through floors and walking through walls? I assume the standard ray/box cast method should be used?
This is typically handled by ray/box-casting yes. Box casting is not possible yet with Rapier and ray-casting is being worked on in the raycast branch.
@stephanemagnenat
Currently I'm using Planck-JS that ignores these contacts as well and it is a big limitation as it prevents the detection of a platform reaching the end of a gap for example.
I think this is generally done using ray-casting or convex-casting (which are both not supported by Rapier yet but are being worked on). Though I agree that doing this with contact events may be more convenient because it allows reusing some contact event handling code you may already have to deal with these platforms too.
Also theoretically, personally I would find it nice that the contact detection, which is a geometry operation, is independent of the actual physics.
Within a single timestep (one call to physics_pipeline.step()
), collision detection and force computation are already independent. Right now PhysicsPipeline
executes both stages automatically but we could probably design it differently to allow executing only the geometry part, and with a second method call the physics part for example. This will become less feasible when we will support CCD (continuous collision detection) though because this introduces a coupling between physics (that governs motion) and collision detection (that uses these motions to compute times of collision exactly) but we are not there yet.
Two things are certain though:
QueryPipeline
which allows to perform efficiently one-time geometric queries (ray-casting, convex-casting, box queries, etc.) on the whole collider set. This means for example that one could use the PhysicsPipeline
for contact determination and physics integration, alongside the QueryPipeline
for individual geometric queries.Anyways, I think that this issues about wanting some contacts ignored by the solver is closely related to #24, as well as (to a lesser extent #3 and #2). So maybe digging into #24 further will actually cover this issue.
I gave this a thumbs up as I was expecting to get contact events for implementing a character controller using a kinematic body with a collider on it and then having various static and dynamic bodies in the world, also with colliders. That said, I don't know if this is necessarily a good way to implement a character controller. I'd probably be happy to be able to build something based on ray-casting or saying something like "this bounding box is going to move linearly from here to here, give me the closest hit if any" and then I suppose one may need to iterate that.
However, if I take a step back, I mostly just want to be able to control the feel of the input controls' interactions with the character. I've seen discussion of attack, decay, sustain, release envelopes applied to animations and regardless of the feel I'm looking for, I expect that I have to do this through controlling a kinematic body if I want the physics engine to simulate the interactions of that body with the other simulated objects. At this point I'd be happy if rapier took care of dealing with object penetration so that I can bump up against walls or 'walk' along the ground, jump on top of things, push dynamic objects, etc rather than me having to reimplement that for no good reason.
I'm undecided and am open for input for ways for kinematic bodies to cooperate with the physics engine. #24 sounds like a good way to open up for flexibility to implement handling for gaps, stairs, etc.
Searching around for more input I found this long and detailed discourse as part of PhysX: https://docs.nvidia.com/gameworks/content/gameworkslibrary/physx/guide/Manual/CharacterControllers.html
It suggests that the kinematic body controller do continuous collision detection (is this what you mean by a box query? I’m imagining that one projects/extrudes the bounding box of the geometry along its trajectory and then tries to see if that intersects with anything, maybe done differently or more completely with dynamic bodies.)
Also it notes that the kinematic body controller should probably specifically handle the interaction on collision with dynamic bodies because a cuboid or capsule collider will tend to apply force not through the centre of mass and so cause the body to rotate which is often not what was intended (e.g. pushing a box.) This sounds like more support for a combination of this issue and #24 - both that the collision event is triggered and that there is a way to override a default dynamic body collision to provide an alternative interaction that makes more sense for what was intended. What do you think of this @sebcrozet ?
For traditional uses of kinematic bodies which don't need any contact info, could this impair performance?
great to see this is merged in! Is there an example available for detecting collision events between non-dynamic rigidbodies? ie something like Unity's OnTriggerEnter()
I've been playing around with the physics hooks but maybe have misinterpreted how they are supposed to be used:
Ok it looks like the solution i was after can be achieved using RapierContext
fn check(rapier_context: Res<RapierContext>, query: Query<Entity>) {
for entity in query.iter() {
for intersection in rapier_context.intersections_with(entity) {
println!("bang! {:?}", intersection);
}
}
}
It would still be nice to have an event-based way to do this, I guess at the moment the best way is to hand-roll our own?
For people who (like me) may stumble upon this issue in the future: in newer versions ActiveCollisionTypes
can be used to enable contacts between static/kinematic bodies.
Currently, the detection of collisions between two static bodies, two kinematic bodies, or one static and one kinematic bodies, will be ignored (the contact points won't even be computed).
It may be useful to have a way to tell Rapier that we do want some contacts between static/kinematic bodies to be computed by the narrow-phase, but ignored by the constraints solver. Maybe that could be useful for character controllers?
I would like to open the discussion on whether this can be useful and why. Please comment or add a :+1: bellow if you are interested in this feature, or :-1: if you think this is completely useless.