Advertisement

Better PhysX Character Controller

Started by February 25, 2017 08:14 PM
4 comments, last by BlueSpud 7 years, 8 months ago

Hey,

I've had a character controller implemented into my engine for a while now using PhysX, and it works decently well, but I'm looking for a better solution. The biggest issue I have is that the character controller doesn't support cylinders because their math is hard to work with, and I've never really liked the way that capsule character controllers gently slide down a 90º drop-off because their bottom is rounded. I also had some issues with collision between the character controller and dynamic objects, and the behavior was inconstant, sometimes not being able to move the dynamic body and sometimes hitting it like a truck.

I've been playing a lot of Natural Selection 2 lately (great game, go buy it if you haven't) which also uses PhysX. They have some behind the scenes videos where they show the PhysX visualizer where they show their character controller as a cylinder. Heres a link if anyone is interested:

I played around in the game for a little bit and noticed that for some of the other characters in the game they use shapes other than cylinders. For instance one of the characters in the game is almost rhinoceros like and uses a large, definitely not cylindrical or capsule shape.

I wanted to revisit my implementation of the character controller and try to make it smoother as well as be a cylinder or another shape. I considered trying to cheat and use a rigid body to represent the character controller and use constraints to keep it upright and set the linear velocity for walking, but I thought that I would ask here before I wasted a bunch of time and effort to see if there are any better solutions. Does any body have any suggestions? I would appreciate any ideas.

Thanks

In the video the shape is not a cylinder - it's a convex hull (approximating a cylinder).

That doesn't help completely, because the supplied PhysX CC doesn't support convex hulls either! However, the collision system in PhysX does support convex hulls, but not true cylinders. I would guess that they either added support for convex hulls to the existing character controller (probably not that hard, since you get the source code), or possibly they just wrote their own CC from scratch.

There are two ways to implement a character controller:

1. As a rigid body that is constrained to stay upright. Move it around with forces, and it will impart forces on other objects, and also receive forces. The big thing here is that it gets updated with everything else, in the single simulation step.

2. As a kinematic shape that is updated separately from the simulation (though typically you'd update all the CCs at once). You've got a slightly less physicsy interaction with other objects, but the argument goes that character movement doesn't tend to look right/be well controlled if it's done through forces, since you never really know what's going to happen (so it's hard to match the animation to it).

This simultaneous/separate update is important if you're using animation on your characters, since the animation you play is tightly coupled to the character movement. Which determines which (it depends on your game)?! Also, if you are using physical simulation on part of your character, that affects things too.

If you've got a large share that hasn't got rotational symmetry then you'll have more work to do, since I don't think PhysX really supports that. For example, if you've got a long character that rotates near a wall, should the CC push out from the wall?

Advertisement

My mistake, it totally slipped my mind that they were using a convex hull when I wrote the post. I took a look at the character controller source and it seems very specialized to just use capsules and boxes, so I doubt that they modified it because it would probably result in redoing the entire controller.

When I thought of using rigid bodies I envisioned using velocity instead of forces, and I actually tried it out. It resulted in a lot of rubber-banding when colliding with static objects. I'm not really very experienced with PhysX, so it was probably just my ineptness. The forces approach seems like it would require a lot of overcomplicating because the force would have be exactly the same as friction once the controller was accelerated to full speed.

As for the kinematic approach, I was under the impression that kinematic objects don't have collisions? I could be wrong but from the Nvidia docs it says "There is no interaction or collision between kinematic actors and static actors." The regular implementation uses sweep tests for the collisions from what I can tell and kinematics just to simulate collision with dynamic bodies. What were you thinking with this one? Its probably the best solution because it gives the most control.

I've personally found it impossible to get a rigid body working as a CC.

My CC does not even get added to the Bullet world. I just maintain a shape and a transform and use Bullet's GJK on its own to manually test the shape against the bodies in the physics world, doing manual position correction and so on.

Lot of work to get it right but this has been the only way I have managed to get a solid CC working.

Havok supply and recommend a CC using a simulated rigid body, and it's really good, from what I remember. They also used to supply a kinematic one, which was also really good (not sure if they still do - haven't looked recently). The point is - either can be made to work... but neither is easy to implement if you want it to work fast and robustly in non-trivial situations (e.g. interact nicely with physical objects, ride on moving objects etc).

Havok supply and recommend a CC using a simulated rigid body, and it's really good, from what I remember. They also used to supply a kinematic one, which was also really good (not sure if they still do - haven't looked recently). The point is - either can be made to work... but neither is easy to implement if you want it to work fast and robustly in non-trivial situations (e.g. interact nicely with physical objects, ride on moving objects etc).


I've tried using both rigid bodies and manual sweep tests. I had some really nasty problems with both, mostly stuttering / bad collision behavior, etc.

I would think that a rigid body would be the best solution as well, so I tried implementing it. I created a dynamic rigid body with a convex shape and set the inertial tensors so it wouldn't rotate and fall over. I then set the linear velocity before I called step simulation. This worked pretty good, but it didn't really slide against the walls and when the rigid body was pushed against the wall at too steep of an angle, it jittered back and forth and I'm not quite sure why. I'm sure there's something physx specific I'm missing but there isn't a whole lot on character controllers in physx from what I've found

This topic is closed to new replies.

Advertisement