What's on the menu?

One thing to know about Unity is that - for better or for worse - it's always changing. The standard way of implementing UIs and player controls has changed quite a bit over the last three to five years. A decent number of the high quality tutorials and tutorial videos out there are becoming dated. I could use the old Unity software and old way of doing things, but I'm making a new game, dammit, and I want to use the latest LTS release from Unity.

Diving in, you'll find that there are a few different ways to do UI in Unity now. It's easy to get overwhelmed. Luckily, the legacy ways of building the UI work just fine for my purposes, so I don't feel bad completely blowing off learning UI Toolkit. I hope this doesn't come back around to bite me, but I think it will be okay.

With that decision made, it's on to the input system. The new input system aims to be much more friendly to cross-platform releases, which is what I hope the Untitled Story Game will become. The decision was made for me, and I dove in head first.

unity-input-actions-dialog

Linking this massively configurable behemoth to the game and to its fledgling menu system proved to be a bit of a challenge. Take a look at this Pause() method along with the hack and its respective TODO.

    public void Pause()
    {
        if (pauseCanvas.gameObject.activeInHierarchy)
        {
            // TODO: find out why `playerInput.actions.FindActionMap("Player").Disable();` doesn't prevent double pause
            return;
        }
        playerInput.actions.FindActionMap("Player").Disable();
        Time.timeScale = 0.0f;
        pauseCanvas.gameObject.SetActive(true);
        gameUiCanvas.gameObject.SetActive(false);
        EventSystem.current.SetSelectedGameObject(resumeButton.gameObject);
    }

Despite the fact that I thought I had disabled the player's ability to pause the game, this method was called each and every time I pressed the Start button. I put the hack in after giving up in figuring out what I was doing wrong.

Dear Reader, if you're still with me, that was just the tip of the iceberg. Reserve your judgements, but I am an invert y-axis man. Yes, I like to imagine that someone is yanking down on the back of my head when I look up. It's just how I am. Anyway, I thought it would be a nice simple proof of concept to implement an Invert Y-axis option! I already knew at this point that an action processor took care of the inverting. I figured I could IntelliSense my way to a solution to updating that input action processor value. I couldn't.

    public void ToggleInvertY()
    {
        playerInput.actions["Look"].ApplyBindingOverride(new InputBinding
        {
            path = "<Gamepad>/rightStick",
            overrideProcessors = "InvertVector2(invertX=false,invertY=" + !invertY.isOn + "),StickDeadzone,ScaleVector2(x=300,y=300)"
        });
        Debug.Log("Processors: " + playerInput.actions["Look"].SaveBindingOverridesAsJson());
    }

I ended up with that magical chunk of code after examining the asset's JSON representation.

I can imagine a title in its mature stage of development saving and loading these InputActionAssets along with the game's save data or profile data. The game asset has the default values - also as json somewhere - so that when the inevitable Restore Defaults button is implemented, that default JSON configuration could simply be copied into the player's configuration. One day I'll get there. For now, it's kludgey code and kludgier menu system.

unity-invert-y-option-proud-papa

Until next time, happy coding!

Add a comment

Previous Post Next Post