How to write a custom physics engine?

Hi,

How would one approach writing their own very basic physics engine in Unity? I mean a very simple collision checking system (example: Bounds.Contians()). My primary confusion is this: What game loop do I go with? FixedUpdate(), Update() or something else?

FixedUpdate() - I like FixedUpdate() in that it goes at a consistent rate (independent of rendering rate). On the other hand I’ve read that the ONLY time you should use FixedUpdate() is when dealing with rigidbodies.

Update() - Seems like it would work as well, in combination with Time.deltaTime of course. But what if the fps gets too low? Then my physics will start to break as Time.deltaTime will be huge (objects will go through each other).

Anyways, any suggestions are welcome.

you should check collision only when you move your object. so im not sure if its something that should be on fixed update or update…
just create a function that moves the object but also check for collision.
if your asking where do you call that function… i think update will be fine.

Physics isn’t just collision detection, though, it’s also collision resolution, forces, velocity, and so on.

Why do you want to write your own? I’m not saying you shouldn’t, I’m just interested to know.

2 Likes

Well if you plan to develop your own physics engine, you will have to deal with your own version of rigidBody, so FixedUpdate seems the right choice, as a start.

P.S. I didn’t realize that you need only collision checking in your engine. If so, that’s not a physics engine, but more of a collision system, and you could simply use Update (combined with some collision prediction functions).

Let me answer that with a question. How would you go about programming games like Super Mario Bros (NES) or Tony Hawk’s Pro Skater? Would you really use a Rigidbody to move a skater around? Watch from 0:28 to 0:46:

What if I wanted to build just a simple shooter that merely required collisions to be tested, but REALLY frequently. If I went with Rigidbody+Collider then you have to set the Fixed Time Step and Maximum Fixed Time Step Allowed to small numbers (0.02 each) and this immediately makes the whole game play in slow motion.

But how will Update() work when there is no limit to how big Time.deltaTime can be? If fps drops below 10 for instance, then Time.deltaTime will be huge and my objects will start going through each other…

A good prediction system takes into account the eventuality that objects might have gone through each other even if they didn’t collide within two frames. Though it would be overkill for complex situations, so it depends on the game you’re making.

Well, yes. Particularly if you wanted to interact with other bodies. Physics systems are about balance, you need to balance everything or it’ll look unrealistic and unresponsive. You can override the velocities of a rigid body at any point if you want a more arcade response, or even use a character controller.

Physx, havok, any physics middleware in AAA games will always have a ton of corrective code to ensure it behaves as the designer intends. This is because a) we do not know the full laws of physics b) no known computer is able to fully calculate our known laws of physics at interactive framerates.

This is because they’re all approximations of physics, and with that in mind you’ll want to use Physx in unity to perform the heavy lifting such as complicated collisions, while your corrective code keeps it behaving how you’d like.

In Physynth, we used physx for everything, but there’s correcting code to ensure forces never explode.

In The Other Brothers we use the character controller in unity (this is actually internally a bunch of raycasts) and Physx box / sphere colliders and triggers, however enemies use raycasts. So you can mix things up as much as you like, use as much or as little of the engine as you like.

The actual collisions between enemies and player when stomping or attacking are done using 2D rect to rect collisions with velocity since they’re infrequent and pre-culled by physx (enemies far away are deactivated when they move out of the camera’s box collider and vice versa). So I tend to use a real mixture, best tool for the job. The reason for manual collisions with attacks is because I prefer to run Physx at a lower framerate for performance, and I need the attacks to never sink in, but always respond with the precise distances.

Also saves me a ton of time and the performance is 60fps on mobile at the moment, no worries there.

For a shootemup, you will probably want 2D rectangle collision, which you can google for a million hits or so. Use in standard update but remember - you need to push the position of the collider ahead of the player or bullets by the velocity, so its always going to be where the rendered image will be, and you use your movement speed * deltaTime for this, the same way as you move your bullets or whatever.

1 Like

hippo is right in that physics in games is a bit of a black art. Knowing a bit about what goes on under the hood can go a long way I think. If you’ve got time on your hands it’s definitely worth writing some simple physics engines to figure out how they work.

I wrote a custom 2D physics engine a little while ago - mainly as a learning exercise and partly because the Physx callbacks didn’t return enough useful information for my liking. I came to the conclusion of controlling everything within my own loop was the best option as the order of various things is quite important. Here’s what my loop looked like, it uses a fixed timer but could be changed to a variable one quite easily.

const float MAX_DELTA = 0.3f;
const float FIXED_TIME_STEP = 0.02f;

public void PhysicsLoop()
{
    float newTime = Time.realtimeSinceStartup;
    float frameTime = newTime - currentTime;

    if (frameTime > MAX_DELTA) frameTime = MAX_DELTA;
    currentTime = newTime;

    accumulator += frameTime * Time.timeScale;

	// Fixed update loop - note it can run multiple times per frame
	while (accumulator >= FIXED_TIME_STEP * Time.timeScale)
	{
	    float step = FIXED_TIME_STEP * Time.timeScale;
	    if(OnPreStep != null) OnPreStep();			
	    Step(step);	
	    if(OnPostStep != null) OnPostStep();
	    accumulator -= step;
	}
	
	float alpha = accumulator / (FIXED_TIME_STEP * Time.timeScale);
	
	foreach(var body in bodies)
	{
		body.Interpolate(ref alpha);
	}
}

Some links I found useful.

http://gafferongames.com/game-physics/
http://www.wildbunny.co.uk/blog/2011/04/06/physics-engines-for-dummies/

I love how you want to write a physics engine… yet are asking us how to write what is a core component of it.

From experience in working on a physics engine in Unity:

You want to use Update(). You can write your own time step accumulator in order to do the same thing Unity does with FixedUpdate, without the minor overhead in using FixedUpdate (for PhysX checks).

FixedUpdate doesn’t actually run at a fixed rate. It runs from 0-whatever (the latter based on your max timestep) times every frame, and stores the delta time left over in a buffer to be added on the next frame. So if your frame was twice as slow, it’ll run it two times - if it was twice as fast, it’ll run 0 times, but store the time passed, then when it runs again it’ll add the previous accumulated time to the new delta time in order to figure out how many times it needs to run.

The loop itself generally goes like this (note that it doesn’t have to):

  1. Check existing collisions and apply an impulse to keep objects falling through each other. Impulses use friction and restitution (bounciness) in their calculations
  2. Calculate forces from user data or other things
  3. Integration (getting new positions and velocities from old data - there are many ways to do this. The most common is Euler integration)
  4. Broad phase for collision checks - check bounding boxes in some sort of spatial tree.
  5. Checking verts for intersections - narrow phase collision tests, lots of math here. We need to check for new collisions and for separations
  6. Clear our forces for the frame and update changes made to bodies (adding, removal, etc.)

There’s more to it, like constraints (joints), multiple iterations, islands/contact graphs/aggregates and all sorts of optimizations, etc.

I recommend the Gafferon Games link to get started: http://gafferongames.com/game-physics/

Computational physics is a huge subject though, so be prepared to invest a lot of time in it.

1 Like

I think this is one of those things where, if you have to ask, then you’re not ready to do it.

Obviously. The same could be said of anything – you’re never ready to do something until after you’ve done it (and often, not until after you’ve done it many times). Doesn’t mean you shouldn’t try and doesn’t mean you shouldn’t ask for advice.

From Wikipedia, the free encyclopedia:
“A physics engine is computer software that provides an approximate simulation of certain physical systems.” Simple collision detection falls into that category.

@OP:
I’m having trouble thinking of a case where you’ll a) need something more performant than PhysX and b) be able to write something yourself that’s more performant than PhysX. However, if you still want to do it, then I would recommend just trying out both FixedUpdate and Update and see what works for you.
I think the bit about low frame rates is a bit moot - if your game is running at below 10FPS then objects going through each other are the least of your worries. :stuck_out_tongue:

4 Likes

When would you call this method? How would you even integrate this with Monobehavior? You cannot put this in update() for example. You would have to ditch the entire monobehavior class, right?

This is a 5 year old thread, if you have a specific question related to the engine today, please start a new topic in the appropriate forum.

1 Like