Closed HugoPeters1024 closed 1 year ago
This is also a major blocker for me, so I went ahead and tried to implement/fix it. I was somewhat successful.
I created a more basic version of the controller that works for me. You can take a look at my fork.
The only real changes were in the cast_shape
section of move_shape
. In essence it's just this portion:
// We hit something, compute the allowed self.
let allowed_dist =
(toi.toi - (-toi.normal1.dot(&translation_dir)) * offset).max(0.0);
let allowed_translation = *translation_dir * allowed_dist;
result.translation += allowed_translation;
let unapplied_translation = translation_remaining - allowed_translation;
// ... (there's some more code here to prevent sliding on shallow slopes)
// project translation onto plane to slide along it
translation_remaining = unapplied_translation
- toi.normal1.scale(unapplied_translation.dot(&toi.normal1));
Unfortunately this broke most of the advanced features of the controller (autostep, unclimbable slopes, collision impulses). I haven't looked at that stuff (yet) so I removed them for now. That's also why I can't really open a PR for this.
I really hope we can get this behavior in KinematicCharacterController
.
Related: dimforge/bevy_rapier/issues/301
After working on it a little bit, I can also report that most tries to fix this eliminate the slope and stair features. Parts of the movement logic happen in the handle_slopes
and handle_stairs
. If the part before, which handles the movement on collisions, is changed to slide along obstacles, it "steals" translation_remaining
from the aforementioned functions, which cannot do their job anymore. This is unfortunate, since to me it seems that the following part must be changed:
let allowed_dist = (toi.toi - (-toi.normal1.dot(&translation_dir)) * offset).max(0.0);
let allowed_translation = *translation_dir * allowed_dist;
This ignores the fact that the individual axis of translation_dir
should have different allowed distances!
The next person working on this might profit from https://github.com/dimforge/rapier/pull/443. I added a wall on the right side of the 2D character controller example that you can press against to test the behavior after changes.
Update: Managed to fix it in #446 after all by going along obstacle after the slope and stair checks :D
One tedious issue that I encounter with the KinematicCharacterController (in both 2d and 3d) is that when I press my character against an object sideways, it no longer slides down, even though it is part of the
translation
. Ideally the velocity is clamped against the normal of surface it collides with.Or perhaps I am using the api wrong?