Page 1 of 1

How to make a Kinematic Character Controller like unity3d's

Posted: Wed May 17, 2017 6:28 am
by Jason
Hi
I'm a newer to BEPU
And want to make a Kinematic Character Controller like Unity3d's.
I don't want my Character Controller push another one,just want it to move certain position, and check collision with other dynamic and kinematic Collisions.When have Collisions, Slip past it or just stop.
How to?

Also I want all dynamic and kinematic collision with each other,just dynamic can be pushed.
And realize a trigger property to make some collisions only trigger with out collisions but not other triggers.

Any suggestion would be great appreciated.
Thanks!

Re: How to make a Kinematic Character Controller like unity3d's

Posted: Wed May 17, 2017 6:18 pm
by Norbo
A full featured character controller is a pretty big topic with lots of small but important details, so I'll instead focus on the simplest level and some approaches to achieving it.

For a simple kinematic character controller, the basic building blocks are something like:
1) Some way of choosing a new position.
2) Detecting collisions at that new position.
3) Correcting for interpenetration at that new position.

The key for solving all of these is that you're responsible for basically everything. Kinematics don't do anything unless you tell them to.

#1 is game specific, but provided that the character isn't moving so fast that it will move all the way through obstacles in a single frame, simply offsetting the position by some desired movement offset would be a starting point. You would also want to handle the effect of gravity somehow- otherwise the character will simply fly off cliffs.

For #2, something like the dynamic character controller's QueryManager.QueryContacts would be useful. The idea is to find all contacts with objects which overlap the kinematic's bounding box. Note that you can change the collision rules of the body to change which pairs show up at all in the body's pair list. You can also just arbitrarily filter which collisions you care about while iterating over the pairs.

#3 requires looking at all the individual contacts detected in the previous phase and correcting the position to minimize all of the penetration depths. Note that just adding up all the normal*depths and applying it as a position displacement only produces fully correct results if the normals are all perpendicular- which is very rare. Instead, a common solution is to redo collision detection after each penetration resolution and iterate over the contacts a few times. In the case of acute angles, it can take quite a few iterations to mostly eliminate penetration. There are a lot of options here, but none of them are super simple or super fast.

Some notes about the above:
1) It doesn't handle upstepping or downstepping. That requires more complex 'next position' heuristics or penetration resolution heuristics.
2) It doesn't handle tunnelling. High speeds could go straight through obstacles undetected. To avoid this you'd have to use sweep tests of some kind. A simple extension would be using a previous center to next center raycast or sphere cast to avoid going through a mesh completely.
3) Since all motion is handled at the position level, collisions with dynamic objects won't be rigid. If the character is permitted to move into some debris object that the collision rules allow collision resolution with, it will be smooshed out by position correction rather than being rigidly bumped out of the way. To address this you'd have to control the velocity instead of or in addition to the position.
4) Characters which rely on repeated collision queries to resolve penetration are going to be pretty slow compared to ones that don't. If you allow 10 penetration resolution iterations, the character will be 10 times more expensive than a regular object. This can limit the number of characters that can exist at once.
5) You'll likely want to manually expand the bounding box of the character controller so that the set of overlapped objects contains all the objects that you might collide with after compensating for penetration resolution. This requires using a callback to adjust the bounding box- something like how the CharacterController.ExpandBoundingBox is hooked to the space.BoundingBoxUpdater.Finishing event.
And realize a trigger property to make some collisions only trigger with out collisions but not other triggers.
I'm not entirely sure about the specifics of what you want here, but it sounds like something that you could do with a combination of collision events and collision rules.

Re: How to make a Kinematic Character Controller like unity3d's

Posted: Wed May 24, 2017 2:06 am
by Jason
:D Thanks for detailed explanation

I'll have a try later