Oh man, when you’re busy with “real life” stuff, time flies. A month has gone by and I’ve barely worked on the game. Incidentally, I am at the hardest part of the project as well, so that doesn’t help. I’m doing tedious slow features that require lots of patience and discipline, and those are hard to come by for me. And there’s no way I’m catching up now, which feels bad (and makes my progress chart horrible). Anyway.
My game is basically a twin-stick shooter. Keyboard + mouse is all fine, but I also need controller support as lots of people play with controllers, especially this action-y shoot-y genre.
So my test controller is an XInput Xbox 360 one, which is a common layout/setup. Hopefully, Rewired plugin can handle any variations between controllers, as I would really hate to need to stock up on various controllers for testing.
Anyway, the main gameplay control layout is like this:
Almost everything is straight-forward — I just need to assign buttons to actions and make sure the game uses input “actions” instead of directly checking buttons and such. I’ve already done most of this. The hard bit is the aiming, because that is technically completely different with the controller. The end result is very similar, but the underlying principles differ in many key features.
Mouse input was “automatic”, but I do need to define the aim actions for my controller:
I need my input manager to be able to handle either mode on demand, so I made it switch to controller or “directional” (as opposed to “direct” aiming mode:
Now I can proceed to rewire and retweak everything aiming-related to work for the controller — if the right analog stick is held down, the player “points” their aim reticle in that direction by a certain amount. In other words, right stick determines the angle for aiming.
This means 3 systems have to use the aim direction according to current input mode — (1) input system itself, (2) camera controller and (3) reticle controller.
(1) Input system needs to provide independent mouse and aim values. All the direct mouse-based controls still need the exact mouse values and I cannot replace them with anything “modular” or shared. So a bunch of math here.
(2) Camera needs to shift according to the aim amount/distance, also dependent on the aim mode. Previously, it just looked at the mouse position and offset itself based on mouse’s distance to the center of the screen. But for the controller logic, it needs to offset based on this new offset value and use different “offset strength” curves for how far to snap the camera (top one maxes out at 0.4, but Unity “stretches” it, so they look the same):
I also need to use the raw aim offset, instead of camera’s smoothed offset, as that is too slow.
And the (3) reticle controller needs to offset the reticle by some predefined amount in the direction of aiming:
The actual distance is just whatever feels good to play with and isn’t strictly speaking exact. I also need to smooth the reticle transition, otherwise it can jump too much due to controller input value abrupt changes (and deadzone issues).
And (as seen in about GIF) this works out fairly well. Now, I don’t play games with the controller and I’ve really not played any twin-stick shooters — I just prefer the precision of mouse. So it’s hard for me to tell if my results are just “good enough” or any better.
An interesting consequence of aiming with a stick is that the aim always resets to 0 when the stick isn’t held and the aim reticle ends up on top of the player. It looks kind of bad:
In fact, I need the reticle controller to gradually fade out the reticle when it reached the player’s position:
And this works out nicely:
The player is still aware where the reticle is, it’s just not getting in the way. It’s also a reminder that the playing isn’t actually aiming at anything in particular.
One caveat, however, is when the player is reloading their weapon:
I want the reload animation to remain visible, because it’s the only UI feedback for reloading.
And that about wraps it for aiming with the controller — a fairly convoluted and intense feature. I’ve never really dealt with this stuff before. But now I have two working modes for controlling and aiming the character. I will need to make a way to select the right one at the start of game and then hot-swap between them. Technically, all the controls work at the same time, only the aiming needs a mutually exclusive selection.