PhysX

On this page I want to try and lead you through the process of how we implemented a PhysX wrapper to our game engine. It is a system I enjoyed working on even though I'm not completely satisfied with the results.

The Problem

None of us in the group had any prior experience working with a physics engine, save for Unity's implemenatation. The interface we ended up creating was largely modeled around which functions existed in Unity, and what we needed for our game.

Our engine works with centimeter as a scale, and it turns out, PhysX really likes working in meters. Which brought it's own little mess into our pipeline. We solved that by dividing everything going in to the PhysX system by 100 (or rather multiplying it with 0.01) and equally when data comes out it is multiplied with 100. It is about as stupid as it sounds, but it got the job done.

We ended up deciding that we needed a reliable collision system, and we needed it to handle moving objects as well. A big part of the puzzle mechanics was the ability to stand on moving objects, elevators and such, and it turns out that PhysX supports this! We also wanted terrain collision, and triggered event through scripting.

Since we are using an ECS we opted to make component classes that holds a pointer to an instance of a wrapper class. Yes, a bit clunky to work with and maintain, but it kept the components clean of any excess PhysX dependencies.

Due to some technical issues in our transform and matrix classes, we saldy had to cut the terrain collision bit from the game, as we didn't have time for it.

The Character Controller

The most important bit of the game, the player character. It's base is an ActorController which is a wrapper for the PxController class. We gave it functions for moving and jumping, which basicly affects the moveData vector, adding a direction and a length to it. This moveData is normalized and passed to the actorController in the Update function to actually move the character around. The Update function also has a little raycast to check if it is grounded or not.

Alright great! We have a capsule character that moves and jumps. What's next?

Well, we wanted to be able to "ride along" with other objects that are moving, and right now we just glide off of everything. Turns out, there are these "behaviour flags" on the PxController, and we needed to tap into these. What they do is basicly check what kind of shape we are colliding with. Is it a box, grab it's movement vectors and apply it to the actor. Is it anything else, just let it slide off.

With the first implementation we had something looking like this.

What we wanted to have was something looking more like this.

Compound Colliders

With our first implementation, each time we created a collider we also created a rigidbody to that collider.. Or vice versa.

Instead we start with creating the shapes, the colliders basicly, and put them in a container component. When the level is done loading, we loop through all the container components and assign all of their colliders to the closest parent rigidbody component. Thus creating a hierarchy where one rigidbody can have many shapes attached to it.

Now when we rotate a rigidbody, all the attached colliders behave as children to it, and the platform moves as intended.

Thoughts

Given the time, I would like to re-write this wrapper from scratch. With what we now know, I think we would be able to get an interface that much more resembles our needs. Right now it feels like it takes a week to implement the smallest change because the functions we need either don't exist, or lie hidden somewhere we can't reach them.

I have however learned a lot of how the PhysX API works, and even though I still spend some time reading the documentation, I feel like I've seen most of it at some point.