Skip to content

Game.UI.InputHintBindings

Assembly: Assembly-CSharp
Namespace: Game.UI

Type: public class InputHintBindings

Base: CompositeBinding, IDisposable

Summary:
Manages input hint data exposed to the UI via Colossal.UI bindings. It builds and maintains a set of input hints (names, priority, whether to show, and items containing control paths + modifiers) based on the game's input system (Game.Input.InputManager). The class: - Registers multiple Colossal.UI bindings (value and getter-map bindings) so UI scripts can query active hints, per-action hints, tutorial hints and the current gamepad type. - Listens to InputManager events (actions changed, enabled actions changed, display names changed, control scheme or active device changed) and marks hints dirty so they will be rebuilt on the next Update. - Produces simplified ControlPath representations for bindings, groups bindings by modifiers and supports special handling for axis-like controls (sticks / dpad). - Exposes an event onInputHintPerformed which is invoked when the UI triggers the matching input hint action.

This class also defines several nested types used for serializing/writing hints: InputHint, InputHintItem, TutorialInputHintQuery, InputHintQuery.

Fields

  • private const string kGroup = "input"
    Used as the prefix group name for the Colossal.UI bindings added by this class.

  • private static readonly string[] axisControls
    Array containing axis-like control base paths: "/leftStick", "/rightStick", "/dpad". Used to simplify directional bindings into single axis paths.

  • private static readonly string[] allDirs
    Array of direction suffixes { "/up", "/down", "/left", "/right" } used when checking for full directional coverage.

  • private static readonly string[] horizontal
    Array { "/left", "/right" } used to detect horizontal-only axis bindings.

  • private static readonly string[] vertical
    Array { "/up", "/down" } used to detect vertical-only axis bindings.

  • private static readonly string[] axes
    Array { "/x", "/y" } used to detect x/y axis bindings.

  • private readonly ValueBinding<InputHint[]> m_ActiveHintsBinding
    Value binding for the currently active hints array exposed to UI under "input", "activeHints". Updated when hints are rebuilt.

  • private readonly GetterMapBinding<InputHintQuery, InputHint> m_HintsMapBinding
    Getter-map binding for per-action hints exposed to UI under "input", "hints". Calls GetInputHint to produce a hint for a requested UI action alias and control scheme.

  • private readonly ValueBinding<int> m_GamepadTypeBinding
    Value binding exposing the currently active gamepad type under "input", "gamepadType". Updated when active device changes to a gamepad.

  • private readonly GetterMapBinding<TutorialInputHintQuery, InputHint[]> m_TutorialHints
    Getter-map binding for tutorial-specific hints under "input", "tutorialHints". Calls GetTutorialHints to build hints for tutorial queries.

  • private Dictionary<(string name, int priority), InputHint> m_Hints
    Internal dictionary storing collected hints keyed by (display name, priority) to allow grouping actions by same display override and ordering.

  • private bool m_HintsDirty
    Flag indicating that hints need to be rebuilt (set by input manager event handlers).

  • private bool m_TutorialHintsDirty
    Flag indicating tutorial hint queries should be updated (set by input manager event handlers).

  • private static Dictionary<IReadOnlyList<ProxyModifier>, List<ProxyBinding>> modifiersGroups
    Static temporary dictionary used when grouping bindings by their modifier lists during hint collection. Uses ProxyBinding.ModifiersListComparer for key comparison.

  • public event Action<ProxyAction> onInputHintPerformed
    Event fired when HandleInputHintPerformed finds a matching InputHint name and forwards the underlying ProxyAction. Subscribers can respond to a hint being triggered from the UI.

Properties

  • No public properties. (All bindings are fields; the public surface is the constructor, Dispose, Update, and the onInputHintPerformed event.)

Constructors

  • public InputHintBindings()
    Initializes and registers Colossal.UI bindings:
  • Adds a GetterMapBinding for per-action hints (m_HintsMapBinding).
  • Adds a ValueBinding for active hints array (m_ActiveHintsBinding).
  • Adds a ValueBinding for gamepad type (m_GamepadTypeBinding).
  • Adds a GetterMapBinding for tutorial hints (m_TutorialHints).
  • Adds a TriggerBinding for "onInputHintPerformed" that calls HandleInputHintPerformed.
  • Subscribes to Game.Input.InputManager instance events:
    • EventActionsChanged
    • EventEnabledActionsChanged
    • EventActionDisplayNamesChanged
    • EventControlSchemeChanged
    • EventActiveDeviceChanged

The constructor prepares this object to serve UI queries and to react to input system changes.

Methods

  • public void Dispose()
    Unsubscribes from InputManager events added in the constructor. Should be called to prevent leaks or callbacks after the instance is no longer needed.

  • private void OnActionsChanged()
    Event handler: marks both m_HintsDirty and m_TutorialHintsDirty and updates the hints map binding (m_HintsMapBinding.UpdateAll()) to invalidate any cached per-action hints.

  • private void OnEnabledActionsChanged()
    Event handler: marks m_HintsDirty true so hints are rebuilt on next Update.

  • private void OnActionDisplayNamesChanged()
    Event handler: marks m_HintsDirty true (display names changed affects grouping/visibility of hints).

  • private void OnControlSchemeChanged(Game.Input.InputManager.ControlScheme controlScheme)
    Event handler: marks m_HintsDirty true (control scheme change can change which bindings are relevant).

  • private void OnActiveDeviceChanged(InputDevice newDevice, InputDevice oldDevice, bool schemeChanged)
    Event handler: if the active control scheme is Gamepad, updates m_GamepadTypeBinding with the currently active gamepad type.

  • public override bool Update()
    Called from the CompositeBinding update loop. Performs:

  • If m_TutorialHintsDirty, updates the tutorial hints getter map binding and clears the flag.
  • If m_HintsDirty, calls RebuildHints(), orders values by priority, updates m_ActiveHintsBinding, and clears the flag.
  • Returns base.Update() result.

  • private void HandleInputHintPerformed(string action)
    Invoked by the trigger binding when UI triggers an input hint action name. Iterates stored hints and if a hint has a matching name, invokes onInputHintPerformed with the underlying ProxyAction.

  • private void RebuildHints()
    Clears m_Hints and iterates over all ProxyAction entries in Game.Input.InputManager.instance.actions. For actions that have displayOverride, calls CollectHints with the current active control scheme translated to DeviceType. This fills m_Hints with InputHint instances grouped by display name and priority.

  • private static void CollectHints(Dictionary<(string name, int priority), InputHint> hints, ProxyAction action, Game.Input.InputManager.DeviceType device, bool ignoreMask = false)
    Static helper: ensures an InputHint exists in the provided dictionary for the action's display override/title and priority, then calls CollectHintItems on that hint with the action, device and transform. When no displayOverride a default name/priority is used.

  • internal static void CollectHintItems(InputHint hint, ProxyAction action, Game.Input.InputManager.DeviceType device, UIBaseInputAction.Transform transform, bool ignoreMask = true)
    Core logic that:

  • Iterates composites on the ProxyAction.
  • Skips composites not matching the device (and optionally the action mask).
  • Groups bindings by their modifiers list into modifiersGroups.
  • For each group, builds an array of control path strings from binding.path, simplifies them (SimplifyPaths), converts them to ControlPath instances, converts modifiers to ControlPath instances, and appends an InputHintItem to hint.items with constructed bindings and modifiers.

  • private static InputHint[] GetTutorialHints(TutorialInputHintQuery query)
    Handles tutorial-specific hint queries. It:

  • Maps certain tutorial action names to actual action names and maps ("Rotate Mouse" -> "Rotate", "Tool Options" -> Navigation/Secondary Action, etc.).
  • Finds the ProxyAction for the mapped map/action.
  • If not found, returns empty array.
  • If Gamepad controlScheme is requested, collects hints similar to RebuildHints and returns the collected dictionary ordered by priority.
  • If query.index >= 0, returns a single InputHint representing the binding at that index that matches the control scheme.
  • Otherwise, returns an InputHint per binding matching the control scheme.

  • private InputHint GetInputHint(InputHintQuery query)
    Getter used by m_HintsMapBinding. Attempts to return a cached value from m_HintsMapBinding.values if the version matches the current InputManager actionVersion. If not cached or stale:

  • Locates a UIBaseInputAction by aliasName matching query.action.
  • If found, creates an InputHint (with name == aliasName, priority == displayPriority, show == true), iterates its actionParts, resolves each actionPart.m_Action to a ProxyAction and calls CollectHintItems with actionPart.m_Transform. Returns the constructed InputHint or null if alias not found.

  • private static bool MatchesControlScheme(ProxyBinding binding, Game.Input.InputManager.ControlScheme controlScheme)
    Returns whether a ProxyBinding corresponds to the requested control scheme:

  • Returns true for Gamepad if binding.isGamepad.
  • For KeyboardAndMouse returns true if binding.isKeyboard or binding.isMouse.
  • Otherwise false.

  • private static void SimplifyPaths(ref string[] paths)
    Attempts to reduce multiple direction-specific control paths into a single axis/base path when possible. For each axisControls base path, checks:

  • If allDirs or axes match, replace paths with basePath.
  • If horizontal matches, replace with basePath + "/x".
  • If vertical matches, replace with basePath + "/y".

  • private static bool MatchesDirections(string[] bindings, string basePath, string[] dirs)
    Helper used by SimplifyPaths. Returns true if bindings contains exactly one binding per dir such that each binding is basePath + dir (length checks used to ensure exact suffix match).

Usage Example

// Create and use InputHintBindings for UI integration
var hintBindings = new Game.UI.InputHintBindings();

// Listen for UI-triggered input hint activation
hintBindings.onInputHintPerformed += proxyAction =>
{
    UnityEngine.Debug.Log($"Input hint triggered: {proxyAction?.title}");
};

// During application shutdown, or when no longer needed:
hintBindings.Dispose();

Notes: - The class is tightly coupled to Game.Input.InputManager, ProxyAction/ProxyBinding/ProxyModifier and Colossal.UI binding types. Use only within the context of the game's modding environment or where those types are available. - Nested types (InputHint, InputHintItem, TutorialInputHintQuery, InputHintQuery) implement JSON read/write interfaces and are used to serialize hint data across UI binding boundaries.