Skip to content
Eric Lowry edited this page Aug 5, 2023 · 16 revisions

📦 Installation

Please refer to the Installation Guide for instructions on how to add InputLayers to your unity project.

🧠 General Concept

InputLayers is a system built on top of Unity's native Input System🔗. More specifically, it is meant to extend the functionality and usability of Input Actions🔗 (referred to as InputActions across this documentation).

The following documentation and accompanying guides require a basic understanding of the InputActions system and how it is configured/used. I will try to be as clear as possible, but I strongly recommend that you first familiarize yourself with InputActions before proceding.

What does InputLayers do?

At its core, InputLayers is about letting you easily have multiple systems/UIs/controllers/… react to the same InputAction without:

  • Having to manually enable/disable input handling for one system if another has taken over.
  • Having to create and configure dozens of ActionMaps🔗 with the same InputActions assigned to them just to ensure manage inputs for all your systems/UIs/controllers/…
  • Risking the integrity of your input system anytime a new system or UI is added to the game.

To achieve this, InputLayers lets you configure Layers sorted into Priorities using a dedicated editor window.
You then use LayeredActions which belong to a specific Layer in place of the default InputActions.

Each LayeredAction points to a specific InputActon you have created in the default editor window, and will react to the InputAction being triggered.
However, the LayeredAction will only register the input and take effect if the Layer it is attached to is active.
And finally, only one Layer can be active at any given time. This works using a simple stack system in which the last layer to have been activated is the only one that can register inputs; and whenever a layer is disabled, the previous layer in the stack takes over.

Priorities simply let you ensure that some layers always take priority over others, regardless of when they were activated. In essence, each priority has its own stack of active layers.

Examples

The best way to understand how this works and how it can be used is through examples. Let's start with a simple example that doesn't take Priorities into account:

Simple Example

Note: This example is illustrated in the `IL_Sample_Basic` example scene available as an optional element of the InputLayers package.

Let's imagine a simple UI with 2 main components:

  1. A simple element that can be interacted with; let's say a circle that appears and disappears when the Enter key is pressed.
  2. A main menu that can be opened/closed using the Escape key, and which contains a single option that can be interacted with using the Enter key.

In a "dumb" implementation of this system, if the same InputAction is used for toggling the circle and for activating the option in the main menu; then if the menu is open and no extra safeguard is put in place, the Enter key would both toggle the circle and activate the menu option.

Now let's configure 2 layers using InputLayers:

  1. Base, the layer we use for our base interactions (here, toggling the circle and opening the menu).
  2. Popup, the layer that will handle inputs for when the menu is open.

Since LayeredActions are only active when their corresponding layer is active (on top of the stack), we simply have to:

  • Start with the Base layer active (using the Start() method somewhere in our code).
  • Have the actions to open/close our menu respectively enable/disable our Popup layer.
  • Handle toggling the circle using the Base layer.
  • Handle activating the menu option using the Popup layer.
  • Make sure that the action to open/close the menu exists both in the Base and Popup layers, so it can be both opened and closed.

This will ensure that pressing the Enter key will only affect the systems relevant to the system/UI that is currently visible on screen.


Advanced Example (using Priorities)

WIP
Naturally, it is best to explore the optional example scenes provided with the InputLayers unity package, and experiment with the code. Though the system may initially seem complex, it is in fact quite simple and easy to use.

If you have any questions or need help understanding these core concepts, feel free to start a discussion.

Usability

InputLayers is designed to work great whether you prefer using C# directly, or using the unity inspector.

I will go over the basic components of using InputLayers in both scenarios. But first, here is some basic info about how you can configure InputLayers:

– Configuration

All system in InputLayers are based around Priorities and Layers.

In order to create and configure these, an editor window is made available in the Unity menu:

You can open this window using the Window/UI/InputLayers dropdown menu at the top of Unity.

For more information about using and configuring this window, check out the Getting Started guide.

– Unity Inspector

Though InputLayers may be better suited as a C# tool for your code, it can also be entirely used within the Unity Inspector.

This means you can control layers and register layered inputs directly from within the Unity Editor window. Two scripts are made available for this purpose:

This script allows you to directly control a given layer. Select the layer you wish to control, and you will then be able to activate/deactivate it either automatically when the OnStart() or OnDestroy() event methods are called, or manually by calling the Activate() or Deactivate() methods from a script or a UnityEvent🔗.

This script serves to give you full control over a LayeredAction.

It will let you assign a Unity InputAction🔗 to a specific Layer, and then control both the layer and InputAction either automatically when the OnStart() or OnDestroy() event methods are called, or manually using the following methods:

– Code

When using InputLayers through code directly, you will mainly be dealing with two elements:

By including a serialized LayeredAction field your scripts, the Inspector will expose some dropdowns allowing you to assign a Unity InputAction🔗 to a specific Layer.

This will allow you to manage both your InputAction directly, and control the associated layer using the LayeredAction's public _layer field.

It is likely that you will have multiple LayeredActions are assigned to the same layer; activating/deactivating the layer with LayeredAction._layer.Activate(); and LayeredAction._layer.Deactivate(); only needs to be done with one of them.

From this point on, you can use the Enable() and Disable() methods (usually in your OnStart() and OnDestroy() event methods) to activate/deactivate the script. And, importantly, you can register callbacks to react to the action being pressed using the onPerformedEvent, onStartedEvent and onCanceledEvent events (see here to understand the difference between them).

This allows you to run some code when the action is performed AND the layer it is assigned to is currently active.

This singleton ScriptableObject is the central reference point used behind the hood by InputLyaers. In some cases, you may wish to reference it directly in order to:

Note: This script functions as a singleton, so any property starting with r_ can be accessed directly (ex: IL_ScriptableRefs.r_activeLayer), while any method or a public property without the prefix will need to be called using the Instance reference (ex: IL_ScriptableRefs.Instance.GetLayerByName("Base")).

💡 Guides & Tips

The steps on how to install InputLayers.

Covers all the basic ways to use InputLayers.

Describes some of the underlying systems used by InputLayers that you may wish to make use of.

🛠️ Codebase

All core InputLayer scripts are stored in the /Lowry/UI/InputLayers/_Scripts/ folder:

All other included files are dependencies, custom editor displays, and tools used for the sample scenes that you are unlikely to need to interact with directly.