Posted October 19, 2019 by Pandaqi
#godot #physics #pressure button #platform #rope physics
Welcome to the twelfth devlog!
The main attraction of level 1 is a huge crane, holding a platform hanging from a rope/chain. You can jump into the platform to move to places you otherwise can’t reach. (You do need to ask another player to stand on the button that makes it rotate.) If you’re very skilled, you can even throw packages into the platform as it swings by, or jump off the platform to other zones.
Today I want to talk about how I implemented these things. (Because I think it’s very interesting, and I will re-use many code/mechanics in later levels.)
Many, many games feature pressure buttons: a button that activates when a player is standing on top of it. When the player moves way, the button moves upward again (usually over a short period of time), until it’s deactivated.
I call it a pressure button, because it reacts to the pressure that is put on it (by the player or by placing something else on the button).
NOTE: You also have games where you press the button by standing next to it and literally pressing a button on your controller. Or buttons that you “press” by rotating something. But so far, I haven’t found a good use for those in my game.
For YEARS I’ve searched for a performant, consistent way to create these buttons.
You don’t want players to accidentally hit the button from the side, causing it to fly all over the level or something.
First, I thought I could just make the button a RigidBody, and make movement fixed to one direction. I could do this with a SlideJoint (which does exactly what you think it does => it allows something to slide only in a certain direction/way), or by checking the option in the editor that limits movement to a single axis.
So I implemented this … and it worked horribly. It was glitchy, the button did NOT move up automatically (or in any desirable way), and ten of these buttons put a strain on the physics engine.
Then a lightbulb went off in my head: what if we simply trick the physics system … by moving a StaticBody?
I made the button a StaticBody, which, as the name implies, is meant for objects that do NOT move. But, for some reason, Godot allows you to move it and the physics (so far) respond realistically.
I placed an Area on top of the button, which checks for other bodies within a certain area. This way, I knew if something was standing on top of the button and I could even get the pressure that object exerts (because I had access to the object’s mass and gravity).
The actual code was simple:
As I implemented this … I realized I didn’t need very precise pressure calculations. So I threw my other ideas out the window, and decided that anything pressing the button was enough to make it go down.
And so far, that has worked wonders. (The pressure button is in the lower right, player 2 jumps on it after a few seconds.)
NOTE: You might have noticed that the button design changed along the way. During my playtesting, I noticed that it was very hard to stand on the button, which became REALLY frustrating as the level progressed. The button also had a weird size, which made it fade into the background – I want it to grab attention, because it’s important that players try pushing this button! So I made it bigger and brighter in … well … all possible ways.
I know that the game will eventually have a load of “interactive objects” that can activate/deactivate something. So I wrote a small system that allows me to select a Node ( = object within the level) and a specific function on that Node, right from the editor.
(There’s not much else to say about it, really. Whenever something happens on the button, it looks up those variables that I set manually, and calls the right function on the right object.)
What is interesting, is something I learned that I never thought about before: different ways of activation.
It’s no rocket science, I just never considered it. Now that I know this, I can be more creative when designing levels, while at the same time optimizing the “intuitiveness” of the interactive objects.
Creating a platform that hangs from a rope, which hangs from a crane that can rotate, seemed like a daunting task.
Luckily, I had used Godot’s joint system before, albeit in 2D (to create a hanging bridge that swings up/down as you run over it).
I had the following plan, and (spoiler alert) it worked the first time:
As I write this, there’s still some tweaking to do: for example, once the platform starts rotating, it somehow never stops. I can fix this by increasing the damping factor on the angular velocity, either via the engine itself or via custom code. But there’s no priority for this, because the level is already quite playable with the bouncy and rotaty platform :p (It even has a silly effect to it, especially when someone mistimes their jump and misses the platform by a hair.)
Rope mechanics are just very fun and fit well in this game.
I’ve written most of these devlogs “out of sync” with the game development, which means that I’m writing this conclusion a few weeks after I wrote the rest of this devlog. And I can say that the bounciness/unpredictability of the platform has been fixed!
I had to make a dedicated model for the platform anyway (the one I used before was outdated and the wrong scale), so I decided to make it slightly larger and push it a bit higher. This makes it easier to get on/off the platform, reduces the amount of collisions between the platform and the terrain, and looks better in general.
(What’s interesting, is that I solved all these problems without tweaking the physics parameters. The lesson here: sometimes you just need to re-do something in a different way, instead of fiddling with physics settings!)
Next devlog, I’ll talk about those zones you’ve been seeing in the footage (where you pick up and drop packages).