Game.Input.InputManager
Assembly: Assembly-CSharp
Namespace: Game.Input
Type: public class
Base: IDisposable, IInputActionCollection, IEnumerable
Summary:
Manages all input for the game: action maps, composite bindings, device pairing and listeners, control schemes (keyboard+mouse vs gamepad), input binding/rebinding, conflict detection/notifications, and input-related events. It wraps Unity's Input System assets (InputActionAsset, InputActionMap, InputAction) into game-specific proxy objects (ProxyActionMap, ProxyAction, ProxyBinding, ProxyComposite) and provides utilities for reading/modifying bindings, creating input barriers, and initializing platform-specific modifiers and masks. The manager also handles device lifecycle (pair/unpair), idle detection, overlay focus, and telemetry.
{{ InputManager is the central entry point for mod code that needs to query or change input bindings, subscribe to input events, or respond to device changes. }}
Fields
-
private readonly InputActionAsset m_ActionAsset
{{ Loaded from Resources("Input/InputActions"). Contains the source action maps used to build the ProxyActionMap collection. }} -
private readonly UIInputActionCollection m_UIActionCollection
{{ UI action definitions loaded from Resources("Input/UI Input Actions") used to create UI aliases for proxy actions. }} -
private readonly UIInputActionCollection m_ToolActionCollection
{{ Tool action definitions loaded from Resources("Input/Tool Input Actions") used to create tool aliases for proxy actions. }} -
private readonly Dictionary<string, ProxyActionMap> m_Maps
{{ All proxy action maps keyed by map name. Each ProxyActionMap wraps a Unity InputActionMap and exposes ProxyAction objects. Mods can use FindActionMap / FindAction to get a ProxyActionMap/ProxyAction. }} -
private Dictionary<InputDevice, DeviceListener> m_DeviceListeners
{{ Device-specific listeners used to detect device activation and raw input. Created during Initialize and populated in AddInitialDevices / OnAddDevice. }} -
private InputDevice m_LastActiveDevice
{{ Tracks the last device that generated activity (used to determine active control scheme and to fire EventActiveDeviceChanged). }} -
private ControlScheme m_ActiveControlScheme
{{ Current active control scheme (KeyboardAndMouse or Gamepad). Changing it updates cursor visibility and mask. }} -
private DeviceType m_ConnectedDeviceTypes
{{ Bitmask of device types currently paired (Keyboard, Mouse, Gamepad). Updated when pairing/unpairing devices. }} -
private DeviceType m_BlockedControlTypes
{{ Device types explicitly blocked. Affects mask calculation for which inputs are accepted. }} -
private DeviceType m_Mask
{{ Internal mask of allowed device types derived from activeControlScheme, overlay state, focus, and blockedControlTypes. Applied to ProxyActionMap instances. }} -
private readonly InputConflictResolution m_ConflictResolution
{{ Internal helper that periodically checks/updates binding conflicts between actions and triggers notifications. }} -
private readonly Dictionary<ProxyBinding, ProxyBinding.Watcher> m_ProxyBindingWatchers
{{ Cached watchers for individual bindings to watch runtime state/changes. }} -
private static IReadOnlyList<CompositeData> m_Composites
{{ Known composite definitions (composite types and component metadata) used to interpret composite bindings and modifier parts. }} -
public static readonly ILog log
{{ Logger used for verbose/info/debug messages in the input manager. }}
Properties
-
public IEnumerable<ProxyAction> actions { get; }
{{ Enumerates all ProxyAction instances from all ProxyActionMaps. Useful to iterate actions, for example to build custom UIs or to inspect bindings. }} -
public static InputManager instance { get; }
{{ Singleton instance accessor. CreateInstance() must be called to instantiate; DestroyInstance() to tear down. Mods should use InputManager.instance to access the manager. }} -
public bool mouseOverUI { get; set; }
{{ Whether the mouse is currently over UI. Setting this fires EventMouseOverUIChanged and influences controlOverWorld. }} -
public bool hasInputFieldFocus { get; set; }
{{ Indicates an input field has IME/text focus. Setting this enables/disables IME and logs a verbose message. }} -
public bool overlayActive { get; }
{{ True while system overlay (e.g., Steam) is active. Overlay state affects masks and whether input is processed. }} -
public (Vector2, Vector2) caretRect { get; set; }
{{ Caret geometry used to position IME cursor when a text field is focused (used by Keyboard.current.SetIMECursorPosition). }} -
public bool controlOverWorld { get; }
{{ True if input should control the world (gameplay) rather than UI. Depends on mouseOverUI and activeControlScheme. }} -
public ControlScheme activeControlScheme { get; private set; }
{{ The active control scheme. Setting updates cursor visibility, refreshes masks and fires EventControlSchemeChanged and telemetry. }} -
public bool isGamepadControlSchemeActive { get; }
{{ Shortcut for activeControlScheme == ControlScheme.Gamepad. }} -
public bool isKeyboardAndMouseControlSchemeActive { get; }
{{ Shortcut for activeControlScheme == ControlScheme.KeyboardAndMouse. }} -
public DeviceType connectedDeviceTypes { get; }
{{ Public view of currently paired device types (Keyboard/Mouse/Gamepad). Use static helpers IsKeyboardConnected / IsMouseConnected / IsGamepadConnected to query. }} -
public DeviceType bindingConflicts { get; private set; }
{{ DeviceType flags indicating which device families have binding conflicts with built-in bindings. Used to show notifications. }} -
public InputUser inputUser { get; private set; }
{{ The InputUser created and used to pair devices with the game's action collection. }} -
public int actionVersion { get; private set; }
{{ Version incremented when actions/bindings change; useful to detect when cached binding state is stale. }}
Constructors
public InputManager()
{{ Creates the InputManager instance. Loads action assets and UI/tool action collections from Resources, builds ProxyActionMap objects for each InputActionMap, wiring them into m_Maps. Does not finish full initialization — call Initialize() or CreateInstance() to finish setup. The constructor logs creation and calls OnFocusChanged with Application.isFocused. }}
Methods
-
public static void CreateInstance()
{{ Creates and initializes the singleton InputManager (s_Instance). Calls the constructor then Initialize(). Use at game startup. }} -
public static void DestroyInstance()
{{ Disposes and clears the singleton instance. Calls Dispose() on the instance and sets s_Instance to null. }} -
public void Initialize()
{{ Performs full initialization: sets up composites, modifiers, masks, aliases, linked actions; creates InputUser and pairs/associates devices; registers InputSystem callbacks, initializes conflict resolution, and creates device listeners. Called by CreateInstance(). Use DeferUpdating() to batch updates during initialization. }} -
public void Dispose()
{{ Tears down device listeners, unregisters InputSystem/PlatformManager callbacks, unpairs devices from inputUser. Called by DestroyInstance. }} -
public void Update()
{{ Tick method called once per frame to update device listeners, track idle input state (Telemetry), update conflict resolution and refresh masks/cursor state. Should be called from main game loop. }} -
public ProxyAction FindAction(string mapName, string actionName)
{{ Convenience: return ProxyAction by map & action name or null if not found. }} -
public bool TryFindAction(string mapName, string actionName, out ProxyAction action)
{{ Safe try-get variant. }} -
public ProxyAction FindAction(ProxyBinding binding)
{{ Lookup action matching a ProxyBinding (by map+action). }} -
public ProxyAction FindAction(Guid guid)
{{ Find a ProxyAction by the Guid of its underlying InputAction (searches all maps). }} -
internal bool TryFindAction(int index, out ProxyAction action)
{{ Lookup a ProxyAction by its integer index (used internally). }} -
public List<ProxyBinding> GetBindings(PathType pathType, BindingOptions bindingOptions)
{{ Returns a flat list of bindings (ProxyBinding) across all proxy action maps. pathType controls whether you want Effective, Original or Overridden paths and bindingOptions filter which bindings to include. Useful for building binding UIs. }} -
public bool TryGetBinding(ProxyBinding bindingToGet, PathType pathType, BindingOptions bindingOptions, out ProxyBinding foundBinding)
{{ Attempts to read a single binding (including modifiers) based on a sample ProxyBinding and the requested path type/options. }} -
public bool SetBindings(IEnumerable<ProxyBinding> newBindings, out List<ProxyBinding> resultBindings)
{{ Atomically set multiple bindings. Uses DeferUpdating() to batch binding overrides then returns the effective bindings after applying overrides. }} -
public bool SetBinding(ProxyBinding newBinding, out ProxyBinding result)
{{ Change a single binding. Validates rebindability, modifier policy, and uses InputActionMap.ApplyBindingOverride to commit changes. Returns the updated binding. }} -
public void ResetAllBindings(bool onlyBuiltIn = true)
{{ Reset bindings back to original paths for either all bindings or only built-in ones. Internally fetches original bindings and calls SetBindings. }} -
public void ResetGroupBindings(DeviceType device, bool onlyBuiltIn = true)
{{ Resets bindings for a specific device group (Keyboard/Mouse/Gamepad). }} -
public ProxyBinding.Watcher GetOrCreateBindingWatcher(ProxyBinding binding)
{{ Returns a watcher for the binding, creating and caching one if necessary (used to monitor running input state). }} -
public List<ProxyComposite> GetComposites(InputAction action)
{{ Returns a list of ProxyComposite for the given InputAction (effective bindings across devices). }} -
public InputBarrier CreateGlobalBarrier(string barrierName)
{{ Creates an InputBarrier that can block or allow groups of actions. Useful for modal UI or temporary input restrictions. }} -
public InputBarrier CreateOverlayBarrier(string barrierName)
{{ Creates a barrier used when overlays are shown (blocks most maps except engagement/splash). }} -
public InputBarrier CreateMapBarrier(string map, string barrierName)
{{ Create a barrier for a single action map. }} -
public InputBarrier CreateActionBarrier(string map, string name, string barrierName)
{{ Create a barrier for a single action in a map. }} -
public void AssociateActionsWithUser(bool associate)
{{ Associates or dissociates this IInputActionCollection with the internal InputUser. Called during Initialize/Dispose. }} -
public void SetDefaultControlScheme()
{{ Sets default control scheme to KeyboardAndMouse. }} -
internal DeferManagerUpdatingWrapper DeferUpdating()
{{ Acquire a deferral wrapper to batch internal action updates and avoid expensive repeated Update/Resolve loops. Use in a using block. }} -
private void CheckConflicts()
{{ Walks all maps and actions and determines binding conflicts between modded and built-in bindings. Updates notification UI and sets bindingConflicts. Triggered when actions change (ProcessActionsUpdate). }} -
private void UpdateCursorVisibility()
{{ Updates Cursor.visible based on the active control scheme and hideCursor flag. }} -
Device and association callbacks: OnDeviceChange, OnAddDevice, OnRemoveDevice, OnDeviceActivated, OnUnpairedDeviceUsed, OnDeviceAssociationChanged, AddInitialDevices
{{ These methods handle device lifecycle and pairing/unpairing logic, and they raise events such as EventActiveDeviceChanged, EventActiveDeviceDisconnected, EventDevicePaired and EventActiveDeviceAssociationLost. Mods can subscribe to events instead of overriding these internals. }} -
Several internal helpers for composite/modifier/mask initialization: InitializeComposites, InitializeModifiers, InitializeMasks, InitializeAliases, InitializeLinkedActions
{{ Called during initialization to prepare composite data, ensure modifier bindings exist, attach mask processors to composite bindings, wire up UI aliases and link cross-action composites. }} -
Utility helpers for binding manipulation: TryGetIterators, TryGetBinding, TrySetMainBinding, TrySetModifierBindings, TrySetBindingModifierProcessor, TryGetComposite, TryGetCompositeInstance, CreateCompositeBinding
{{ Lower-level helpers used by GetBindings/SetBinding/SetBindings to locate binding iterators, inspect/override binding paths and processors, and create composite bindings programmatically. }}
Events (important subscribers):
-
public event Action<ControlScheme> EventControlSchemeChanged
{{ Fired when activeControlScheme changes. }} -
public event ActiveDeviceChanged EventActiveDeviceChanged
{{ Fired when the active InputDevice changes. Signature: (newDevice, oldDevice, schemeChanged). }} -
public event Action EventActiveDeviceDisconnected
{{ Fired when the active device is disconnected. }} -
public event Action EventActiveDeviceAssociationLost
{{ Fired when the platform/device association is lost for the active device. }} -
public event Action EventDevicePaired
{{ Fired when a device has been (re)paired to the game's InputUser. }} -
public event Action EventActionsChanged
{{ Fired when the actions/bindings set has changed (actionVersion increments). }} -
public event Action EventEnabledActionsChanged
{{ Fired when enabled actions change. }} -
public event Action EventActionMasksChanged
{{ Fired when action masks are updated. }} -
public event Action EventActionDisplayNamesChanged
{{ Fired when action display names (UI names) change. }} -
public event Action<bool> EventMouseOverUIChanged
{{ Fired when mouseOverUI changes. Provides the new boolean value. }} -
internal event Action EventPreResolvedActionChanged
{{ Internal: fired before resolved action changes. }}
Usage Example
// Create and initialize input manager (usually done by game startup code)
Game.Input.InputManager.CreateInstance();
// Access the singleton
var input = Game.Input.InputManager.instance;
// Subscribe to control scheme changes
input.EventControlSchemeChanged += scheme =>
{
Debug.Log($"Control scheme changed: {scheme}");
};
// Find a proxy action and inspect bindings
var zoomAction = input.FindAction("Camera", "Zoom");
if (zoomAction != null)
{
var composites = input.GetComposites(zoomAction.sourceAction);
foreach (var comp in composites)
{
Debug.Log($"Composite for device {comp.m_Device}:");
foreach (var b in comp.bindings)
Debug.Log($" - {b}");
}
}
// Reset all non-rebindable built-in bindings back to original
input.ResetAllBindings(onlyBuiltIn: true);
// When shutting down:
Game.Input.InputManager.DestroyInstance();
{{ Notes: Many operations that mutate bindings or action structure should be done inside a DeferUpdating() block (InputManager.DeferUpdating()) or rely on SetBinding(s) which use deferral internally. Use the Proxy* wrapper classes to avoid dealing with raw InputAction internals where possible. For modders wanting to add new action maps or bindings at runtime, use AddActionMap / CreateCompositeBinding and then UpdateActionInKeyActionMap / ProcessActionsUpdate as needed. }}