I’ve been meaning to take a serious, serious look at this for a while; previous attempts have been limited to the example projects on the Community Forums. With our current distraction project, we were looking for some options on how to quickly prototype the game and get some FPS action happening, without the need for a complete collision and physics system development, by ourselves. We’ve been using the inbuilt BEPU implementation quite successfully for a while now. For Y3030 it’s totally fine, it gives us the movement required for our floating objects and we can push them around as we like. When we attempted to migrate this approach in to an FPS environment a few new limitations became apparent for us. The most significant being how to move and control enemy players. For the main character, there is a Character Controller class that is provided by SunBurn and it’s awesome, we had a character running and jumping in a matter of minutes (Check out the Dojo Sample for more on this) but we couldn’t get anything working satisfactorily for enemy characters because of sliding and how a physics push works.
Pushing my enemies
The concept of pushing an object with a force, isn’t unique to BEPU or the SunBurn implementation but it brings in other considerations when the rest of the Physics engine is so cool. e.g. If I put a door up in the middle of a field and then push the door forward, the door will fall over. If I put a big car in the middle of a field (say a rectangular box) and push that (with an appropriate increase in force) the car will move forward, it won’t tip over. This is simply because of where the balance point is for the object, the sliding force applied and a few other parts of the equation that aren’t as simple.
For the inbuilt BEPU both of these scenarios work perfectly and our tests past with flying colours.
However when we put an enemy character in the game and tried the same thing, he fell over like a plank of wood. When you pause for a moment, it makes sense. What gives us the ability to walk, isn’t that we are a big giant rectangular box lying on the floor but that we have a whole heap of stuff going on for us to maintain our balance – what we were missing was a way to tell the inbuilt BEPU implementation to fake this. It’s obviously possible because that’s how the character control class works but as we don’t have access to the code, can’t override the requirement to map the character control to an actual controller, it’s a bit limiting for us. I explored this issue in a post on the forums but basically ended up resorting to a hack which would reposition the object to an upright position each update. http://www.synapsegaming.com/forums/t/3364.aspx
While this appeared to sort of work, the technical debt of our hack quickly racked up when we saw that the hack was also reducing the effectiveness of the worlds gravity, objects were no longer hugging the ground as expected. Through the process of removing the force and reapplying it we were severely limiting the amount of gravity force applied to the enemies each update. The end result was basically floating enemies (I guess this would have been fine if we were fighting angels, but since our enemies are Zombies, it’s not quite appropriate.)
Which brings us back to needing a way to push enemies, keep them upright and not falling over (unless we want them to) and having a correct amount of gravity applies to them.
Inbuilt exist stage left
To setup the BEPU plugin download it from the community section on the website (I grabbed the source version so I can play with it if I need to). If you get the precompiled version you can just install it like a normal plugin, with the source version you may need to extract it yourself (I use 7zip). Copy the folder to your project and add the relevant projects to your solution. Build the projects, assuming everything is good we are right to continue.
If you are migrating from an existing Physics implementation, you will need to remove the existing manager. You will likely have added it like this:
sceneInterface.CreateDefaultManagers(RenderingSystemType.Forward, CollisionSystemType.Physics, true);
Change the CollisionSystemType to none so it looks like this:
If your migrating an existing solution, it’s best to go in to the Game, launch the editor and strip out all of the existing items making use of the inbuilt BEPU implementation, other wise you will just end up with a shopping list of run time errors. e.g. remove components from objects that rely on Physics, remove any player controls etc.
You’ll likely still have some stuff to comment out but don’t worry, it gets better; to find them just comment out the using statements for the Physics implementation.
using SynapseGaming.LightingSystem.Collision; //using SynapseGaming.LightingSystem.Collision.Components; //using SynapseGaming.LightingSystem.Collision.Controllers;
Also remove the reference from your project
Once you have a build that compiles and you can get in to the editor, consider it safe to move on.
Greedy Goblin Enters Stage Right
Add a reference to the Plugin Project:
Then find the project:
If you’re targeting the Xbox, add it’s reference now as well so you don’t forget.
Add using Statement:
Because we are using the code version of the project (well at least I think that’s why) we need to add tell SunBurn to load the plugin. There will be a line in your main game class like this: sunBurnCoreSystem = new SunBurnCoreSystem(Services, Content); Add the reference immediately below that, as such:
// Create the lighting system. sunBurnCoreSystem = new SunBurnCoreSystem(Services, Content); SunBurnCoreSystem.Instance.ManuallyLoadPlugin<BEPUPlugin.BEPUPhysicsPlugin>();
If everything is working as expected, you have now just removed the inbuilt SunBurn implementation of BEPU and replaced it with CJ’s plugin. To check, launch the game, then the editor, right click on an scene object and check that you can see the BEPU plugin options:
It’s Different, Not Harder, Just Different
With the BEPU Plugin, enabling Physics on an Object is a bit different from using the inbuilt physics implementation. Normally you would click on the scene object and then be able to directly control it’s Physics properties. With the BEPU plugin, there are a heap of additional options that aren’t covered in the standard menus; as such we need to add a Physics component to each object.
Right click on the object in the editor and chose the appropriate component for the shape:
When you click on the component a new menu for the BEPU options appears.
These sections from the menu are for the BEPU box component:
There are a lot more options exposed for the inbuilt functionality of BEPU here than are available within the inbuilt implementation.
Take this capsule, it’s your medicine
Of particular note and the driving factor for us to use the Plugin Implementation, is the ability to lock a rotation. In this instance we can lock the rotation of the character so that they wont fall over like a plank of wood. Additionally the BEPU plugin offers us the physics type of capsule, which is perfect for a walking character. The following sections are for the capsule type (The first part is the same as the box type):
The main difference in the second half is that we don’t have dimensions mapped out as X,Y,Z but rather just a height and a radius for the capsule.
As you can see in this screen shot, we’ve also Locked the X, Y and Z axis – this is so the character can’t fall over in any direction. This doesn’t prevent us from rotating the character out side of the physics calculation, say when we want the character to turn around but it means the physics engine won’t be calculating any rotations for this object.
A small little obligatory video demonstration:
Greedy Goblin Software have recently just released their SunBurn Vehicle Plugin, for their BEPU Plugin Implementation. Go check it out here (and buy it from them too) http://www.greedygoblinsoftware.co.uk/SunBurnVehiclePlugin.aspx
Watch the video at the end of the page to get a quick understanding of how awesome the Vehicle Plugin is (Or click on this link: http://www.youtube.com/watch?feature=player_embedded&v=ax1eu5Lm_kQ)