Happy Tuesday everyone! I’m back with another programming related post but this time in a little different format. This time we’re going to take a look at the very foundation of platforming: physics.
The first question to answer is what does physics actually mean for us? For the purposes of this post, we are dealing with movement and responding to collision. In order to respond to a collision, we first have to detect it which is a process called, unsurprisingly, collision detection. Collision detection is a broad and complex subject that we won’t go into here and as it turns out, Blightmare just uses the built-in offering from Unity so I haven’t implemented collision detection for this project at all.
Okay. The first step is getting some movement going at all. Otherwise, there’s no way to collide with anything at all! There are undoubtedly many ways to go about modelling motion and some of them may even feel fun to play, for example, you could just add a bit to the current position every frame, possibly changing the direction based on input, and now you have a simple controllable player. The problem with this is that it doesn’t feel very good or natural. It feels kind of harsh and abrupt. There’s no “weight” to Blissa or any momentum feeling. Take a look at that here:
So how can we make things feel a bit more realistic? Well why not just take a look at what actually happens in nature. You may recall something called “newtonian mechanics” or “classical mechanics” from school or even from an earlier blog post! That is exactly what we need here. I will skip the derivation part for now, and get to the good stuff which is the equation of motion.
This tells us what the next position should be as a function of our current position, our current velocity, our current acceleration, and the amount of time that has passed. Okay great, but how do we actually make sense of all of that? Well, we can extend the previous sample to show how this works. Instead of just adding some movement each frame, I will apply a bit of acceleration in the direction of an arrow key and then we will let the equation determine the rest. We have to remember to update the velocity as well each frame by adding the acceleration * dt. This is called Euler Integration (among other similar names) and is a very simple approximation to the real equations of motion. Take a look:
As you maybe can see, this is pretty hard to control and is very “slidey” but it does have a nice smoothness to it, so I guess that’s a plus.
We’re missing a bit of directionality in the simulation right now; it’s hard to get our bearings. In the real world, we know down is down because it’s the direction gravity “pulls” things. We can add that to our simulation as well! Gravity is just a force after all, and we’re actually well equipped to handle forces. You may recall another equation from that same class:
This is telling us how to relate a force to an acceleration. They are related proportionally by mass. We can assume for a moment that our player has a mass of 1 and then we can just directly use a force as an acceleration. Okay great, so now we just add a constant – applied every frame exactly the same – “down” acceleration for gravity and take a look at the example again:
Note that I didn’t do any input in that video. Okay great, so we fall off the screen. That’s not super helpful. Time to add some ground in. Great, check this out:
Oops. The ground won’t stop us by itself! Here comes the collision detection and response part. Remember that we’re going to just use the collision detection that is built in, so we have the ability to know when we are about to move into something. The way that works is that we test the movement that we want to do before we do it. The collision system will tell us how much of the desired movement can be done before a collision which we use to determine what we want to do. If the whole movement can be done without collision, then we just do it. If anything less than the whole movement can be done, then we do whatever we are allowed to do – without colliding – and we know now that we collided with something. Let’s take a look at what that looks like in action:
Cool! Now we stop on the ground and we can still go up, left, and right. It’s hard to tell from the video, but in order to go back up I have to input “up” for quite a while. What’s going on here? It’s the collision response. All we are doing is making sure we don’t pass through the ground by stopping invalid movements, but the other values in our simulation – velocity in particular – are not aware that any collision has happened. What that means is that we keep accumulating “down” velocity from gravity while we’re just sitting on the ground and trying to get up off the ground again has to fully counteract all the accumulated gravity before we will see movement. We know that the ground is always flat and below us, so we can just stop our downward velocity when we collide and that should take care of it. At the same time, I’m going to boost the “up” or “jump” acceleration but make it only happen for a single frame to give a nice crisp pop to the jump. Take a look:
Now we’re really getting somewhere! There’s a number of things that we still have to do, specifically: deal with the difficult to control left/right movement, and we have some work to do on the jump itself because it feels a bit “floaty.” I’m going to do a whole post soon on jumping because it’s so important to platformers, and it’s surprisingly complex and while we’re there we may talk briefly about what to do with the left/right movement to make it a bit “tighter”, but this post is already probably too long!
I really enjoy simulations like this, and physics in particular, so it’s easy for me to get carried away. I hope you’ve enjoyed this post and if you are liking the game, please wishlist Blightmare on Steam and follow us on Twitter for the latest updates. Cheers!