Input is at the heart of every game. The TopDown Engine is no exception. It currently supports mobile controls (iOS, Android…), keyboard, gamepad (setup for windows xbox pad but feel free to rebind the keys for other controllers), and mouse.
By default the keyboard layout has been created to support 4 simultaneous players. Now that may not be very comfortable for a single player game, feel free to remap the buttons to suit your needs (see the following section). In any case, here is the default layout (click on the image to expand) for Player 1 (check out the input settings for other player bindings):
Input Settings - How to change key bindings?
For keyboard and gamepad (and to a lesser extent mouse), key bindings are defined, like in any good Unity project, via the native Input settings. You can access these via the top menu Edit > Project Settings > Input. This should open a quite large list of “axis”. If you’ve never seen this panel before, maybe have a look at the official documentation first.
Now that list is pretty long. That list has been filled to support 4 players (you could add more if you want), and proposes one key configuration. Feel free to edit each of these to rebind the keys to your preference.
Input Manager and GUI
To move your character on screen, you usually use input, whether it’s via touch on a screen or by pressing mechanical keys. To handle input detection and pass it to your Character, the TopDown Engine uses an Input Manager. Most levels of the TopDown Engine have a UI Camera in them. This UI Camera prefab also has, nested inside it, a bunch of mobile controls used to control the player when playing on mobile. For that reason, and to make binding easier, you’ll find the InputManager at the top level of the UICamera prefab. You can decide to place it on its own game object if you prefer.
The Input Manager is quite a long class. If you take a look at it, you’ll see it’s actually not too complex, just very verbose. It has a lot of methods that you’ll be able to bind to your mobile controls, and manages a small state machine for each of the registered buttons.
From its inspector you’ll be able to specify the PlayerID (see the next section for more on that), whether or not you want to use mobile detection or force mobile controls. You can also decide whether you prefer virtual arrows/dpad or virtual joystick. And finally you can set smooth movement on or off (should a press on left be instant or quickly lerped?), and the horizontal and vertical thresholds.
One thing here that is really important to understand is the PlayerID notion. The engine is able to send input from the InputManager to playable characters in the scene (objects with a Character component whose type is set to Player). Each InputManager has a PlayerID attribute, and it’ll send its information to all characters whose own PlayerID attribute match it. So there are a few ways this can work :
- The most common way is to simply let the engine handle this. Add an InputManager to your scene, set its PlayerID to “Player1”. Then in the LevelManager, when you add your character, have the “Auto attribute player IDs” checkbox checked, and it’ll automatically give the playable character the “Player1” ID. If you are in a multiplayer level use “Player2”, “Player3” and “Player4”. You can add your own of course, but these are the default ones.
- You can also set the PlayerID on the prefab. For example you could have a Dog character, whose PlayerID is “JoeTheDog” (why not?). If you add an InputManager to your scene and want it to target that Dog character, set its own PlayerID parameter to “JoeTheDog”. Press play and you should be able to control your Dog character. That method is great if for some reason you don’t want to use the Level Manager and want to instantly move a prefab in the scene.
I use that second method a lot when tweaking a character. Let’s say I want to change the Jump behaviour of my character. I’ll just copy my character’s prefab, put that copy in the scene, set its PlayerID to Player1. Then in the LevelManager I put the original prefab as the Player Prefab. I press play and I’m now controlling two characters with the same input. I can then change the jump settings on one of them (or even add a new Jump script in place of the old one), and play test both very fast to see if my changes are improving the gameplay.
How does platform detection work?
From the InputManager’s inspector you can turn auto mobile detection on or off.
If you unfold the UICamera prefab, you’ll see it contains quite a lot of stuff, and notably Arrows, Joystick and Buttons canvas groups. They’re disabled by default to allow for simpler level editions but you can turn them on if you prefer, or to tweak them. These are then bound to the GUIManager component (among other stuff). Mobile detection works in a very simple way : if you’re targeting a mobile platform (iOS or Android), it’ll show the controls when you press play. If you’re targeting another platform, it’ll hide and disable them. You can also force one mode or the other from the inspector.
Virtual Arrows, Joysticks and Buttons
The asset comes packed with a fully functional arrow D-pad, a joystick and some buttons, but of course you can remix all that, add buttons, add joysticks, etc. to match your own gameplay.
Mobile arrows are very simple, you just need an MMTouchAxis component on a Rect+CanvasGroup object. Then in its inspector you need to set the axis value (usually -1 for left/down or 1 for right/up). Then you need to bind it to your InputManager, simply on the AxisPressed event. To do that, just drag your InputManager (in most cases the UICamera prefab in your scene) onto the little box below “runtime only”, and then select the appropriate method (SetVerticalMovement, SetHorizontalMovement, or their secondary counterparts).
Mobile joysticks are even easier to setup. Just add a MMTouchJoystick component to a Rect+CanvasGroup object, define which axis are enabled (you may want an horizontal only stick for example), the max range (how far the knob can move from its base), and then you bind your input manager to it. Note that you’ll also need to specify a target camera (usually your UICamera).
Buttons work in the same way too, but for them you’ll be able to specify three different events : button down (when it’s pressed for the first time), button up (when it’s released), and button pressed (when it’s being pressed at a certain frame). This will allow you in your Character Abilities (for example) to call certain methods when a button gets released for example. You don’t have to bind all events if you’re not using all of them.
The TopDown Engine includes another of More Mountains’ assets : Nice Touch. Don’t buy it if you already own the TopDown Engine! I created Nice Touch to provide a simple and fast input solution. It handles keyboard, gamepad, mouse, and touch input. There are a lot of other input solutions out there. Nice Touch/MMControls were created to give a simpler alternative, faster to setup, without unnecessary settings. Feel free to not use these and replace them with your own.
You’ll find these scripts into MMTools/MMControls. That same folder also includes a test scene : MMControlsTestScene. You’ll want to keep that folder in your game.