Skip to content

Instantly share code, notes, and snippets.

@phosphoer
Last active June 10, 2024 23:20
Show Gist options
  • Select an option

  • Save phosphoer/87f87fe5f99c4331bd15d4b762e1a572 to your computer and use it in GitHub Desktop.

Select an option

Save phosphoer/87f87fe5f99c4331bd15d4b762e1a572 to your computer and use it in GitHub Desktop.

Revisions

  1. phosphoer revised this gist May 23, 2023. 1 changed file with 17 additions and 40 deletions.
    57 changes: 17 additions & 40 deletions ControllerIconMapDefinition.cs
    Original file line number Diff line number Diff line change
    @@ -37,18 +37,21 @@ public static void GetElementMapsForAction(int actionId, Rewired.Player player,

    public InputIconMapDefinition GetMapForHardware(Rewired.Controller controller)
    {
    if (controller == Rewired.ReInput.controllers.Keyboard)
    return keyboardMap;
    else if (controller == Rewired.ReInput.controllers.Mouse)
    return mouseMap;
    EnsureControllerMaps();

    string hardwareTypeGuid = controller.hardwareTypeGuid.ToString();
    foreach (var controllerMap in controllerMaps)
    if (_controllerIdMap.TryGetValue(hardwareTypeGuid, out InputIconMapDefinition hardwareMap))
    {
    if (controllerMap.ControllerGuid == hardwareTypeGuid)
    return controllerMap.IconMap;
    return hardwareMap;
    }

    if (controller.type == Rewired.ControllerType.Joystick)
    return gamepadMap;
    else if (controller == Rewired.ReInput.controllers.Keyboard)
    return keyboardMap;
    else if (controller == Rewired.ReInput.controllers.Mouse)
    return mouseMap;

    return null;
    }

    @@ -64,23 +67,15 @@ public bool GetIconsForAction(int actionId, Rewired.Player player, List<InputIco
    // Store previous icon count so we can determine whether we successfully found more
    int prevCount = inputIcons.Count;

    // Try to find a specific templated input icon map for this controller
    if (_controllerIdMap.TryGetValue(lastController.hardwareTypeGuid.ToString(), out InputIconMapDefinition specificMap))
    var iconMap = GetMapForHardware(lastController);
    if (iconMap == mouseMap || iconMap == keyboardMap)
    {
    FillInputIcons(inputIcons, specificMap, player, lastController, actionId);
    FillInputIcons(inputIcons, mouseMap, player, Rewired.ReInput.controllers.Mouse, actionId);
    FillInputIcons(inputIcons, keyboardMap, player, Rewired.ReInput.controllers.Keyboard, actionId);
    }
    // Otherwise, fallback to the default generic mappings
    else
    {
    if (lastController.type == Rewired.ControllerType.Joystick)
    {
    FillInputIcons(inputIcons, gamepadMap, player, lastController, actionId);
    }
    else
    {
    FillInputIcons(inputIcons, mouseMap, player, Rewired.ReInput.controllers.Mouse, actionId);
    FillInputIcons(inputIcons, keyboardMap, player, Rewired.ReInput.controllers.Keyboard, actionId);
    }
    FillInputIcons(inputIcons, iconMap, player, lastController, actionId);
    }

    return inputIcons.Count > prevCount;
    @@ -97,26 +92,8 @@ public InputIcon GetIconForInput(Rewired.ActionElementMap elementMap)
    EnsureControllerMaps();
    Rewired.Controller controller = elementMap.controllerMap.controller;

    // Try finding a specific controller icon map
    InputIconMapDefinition iconMap = null;
    _controllerIdMap.TryGetValue(controller.hardwareTypeGuid.ToString(), out iconMap);

    // If we didn't find one, fallback to one of the default generic icon maps
    if (iconMap == null)
    {
    if (controller.type == Rewired.ControllerType.Joystick)
    {
    iconMap = gamepadMap;
    }
    else if (controller.type == Rewired.ControllerType.Keyboard)
    {
    iconMap = keyboardMap;
    }
    else if (controller.type == Rewired.ControllerType.Mouse)
    {
    iconMap = mouseMap;
    }
    }
    // Get the icon map for this hardware
    InputIconMapDefinition iconMap = GetMapForHardware(controller);

    if (iconMap != null)
    {
  2. phosphoer revised this gist Mar 14, 2023. 2 changed files with 169 additions and 51 deletions.
    112 changes: 73 additions & 39 deletions ControllerIconMapDefinition.cs
    Original file line number Diff line number Diff line change
    @@ -1,7 +1,7 @@
    using UnityEngine;
    using System.Collections.Generic;

    [CreateAssetMenu(fileName = "new-controller-icon-mapping", menuName = "Controller Icon Mapping", order = 0)]
    [CreateAssetMenu(fileName = "new-controller-icon-mapping", menuName = "Controller Icon Mapping")]
    public class ControllerIconMapDefinition : ScriptableObject
    {
    [SerializeField]
    @@ -24,7 +24,6 @@ private class ControllerMapPair
    public InputIconMapDefinition IconMap = null;
    }

    private static List<Rewired.ControllerTemplateElementTarget> _elementTargets = new List<Rewired.ControllerTemplateElementTarget>();
    private Dictionary<string, InputIconMapDefinition> _controllerIdMap;

    public static void GetElementMapsForAction(int actionId, Rewired.Player player, List<Rewired.ActionElementMap> elementMaps)
    @@ -36,22 +35,21 @@ public static void GetElementMapsForAction(int actionId, Rewired.Player player,
    }
    }

    public static int GetTemplatedInputId(Rewired.ActionElementMap elementMap)
    public InputIconMapDefinition GetMapForHardware(Rewired.Controller controller)
    {
    Rewired.Controller controller = elementMap.controllerMap.controller;
    if (controller == Rewired.ReInput.controllers.Keyboard)
    return keyboardMap;
    else if (controller == Rewired.ReInput.controllers.Mouse)
    return mouseMap;

    int inputId = elementMap.elementIdentifierId;
    if (controller.templateCount > 0)
    string hardwareTypeGuid = controller.hardwareTypeGuid.ToString();
    foreach (var controllerMap in controllerMaps)
    {
    _elementTargets.Clear();
    controller.Templates[0].GetElementTargets(elementMap, _elementTargets);
    if (_elementTargets.Count > 0)
    {
    inputId = _elementTargets[0].element.id;
    }
    if (controllerMap.ControllerGuid == hardwareTypeGuid)
    return controllerMap.IconMap;
    }

    return inputId;
    return null;
    }

    // Find icons for an input action, based on whatever the current detected controller type is
    @@ -98,8 +96,6 @@ public InputIcon GetIconForInput(Rewired.ActionElementMap elementMap)
    // Get info about the input action
    EnsureControllerMaps();
    Rewired.Controller controller = elementMap.controllerMap.controller;
    int templatedId = GetTemplatedInputId(elementMap);
    bool isAxis = elementMap.elementType == Rewired.ControllerElementType.Axis;

    // Try finding a specific controller icon map
    InputIconMapDefinition iconMap = null;
    @@ -122,7 +118,12 @@ public InputIcon GetIconForInput(Rewired.ActionElementMap elementMap)
    }
    }

    return iconMap != null ? iconMap.GetInputIcon(templatedId) : null;
    if (iconMap != null)
    {
    return iconMap.GetInputIcon(elementMap, controller);
    }

    return null;
    }

    private Rewired.Controller GetPlatformDefaultController()
    @@ -156,45 +157,78 @@ private void FillInputIcons(List<InputIcon> inputIcons, InputIconMapDefinition i
    Rewired.InputAction action = Rewired.ReInput.mapping.GetAction(actionId);
    foreach (var elementMap in player.controllers.maps.ElementMapsWithAction(controller, actionId, skipDisabledMaps: false))
    {
    int inputId = elementMap.elementIdentifierId;
    if (controller.templateCount > 0)
    {
    _elementTargets.Clear();
    controller.Templates[0].GetElementTargets(elementMap, _elementTargets);
    if (_elementTargets.Count > 0)
    {
    inputId = _elementTargets[0].element.id;
    }
    }

    // Debug.Log($"Getting icon for inputID {inputId} for action {action.name}");

    var inputIcon = iconMap.GetInputIcon(inputId);
    var inputIcon = iconMap.GetInputIcon(elementMap, controller);
    if (inputIcon != null)
    inputIcons.Add(inputIcon);
    else
    Debug.LogWarning($"Failed to get input icon for action {action.name} with input id {inputId}");
    Debug.LogWarning($"Failed to get input icon for action {action.name} with input id {elementMap.elementIdentifierId}");
    }
    }

    // Fill input icons using just a controller map and an action, with no controller object
    // This uses the default rewired gamepad template which most gamepads implement
    private void FillInputIcons(List<InputIcon> inputIcons, ControllerMapPair controllerMap, int actionId)
    // NOTE: Using this will bypass any player-specific mappings!
    private void FillInputIcons(List<InputIcon> inputIcons, ControllerMapPair controllerIconMap, int actionId)
    {
    // Debug.Log($"Getting input icon for action {actionId} and controllerMap {controllerMap.Name}");

    // Apply layout rule sets based on controller type, kind of a hack?
    // This allows Switch to properly show the correct mapped buttons while no controller is connected
    int layoutId = 0;
    var ruleSets = Rewired.ReInput.players.GetPlayer(0).controllers.maps.layoutManager.ruleSets;
    foreach (var ruleSet in ruleSets)
    {
    foreach (var rule in ruleSet)
    {
    // Debug.Log($"Comparing rule with hardware id {rule.controllerSetSelector.hardwareTypeGuid.ToString()} to {controllerMap.ControllerGuid}");
    if (rule.controllerSetSelector.hardwareTypeGuid.ToString() == controllerIconMap.ControllerGuid)
    {
    layoutId = rule.layoutId;
    break;
    }
    }
    }

    // Now get the mapping for this controller template and layout
    Rewired.InputAction action = Rewired.ReInput.mapping.GetAction(actionId);
    Rewired.ControllerIdentifier controllerIdentifier = new Rewired.ControllerIdentifier();
    controllerIdentifier.hardwareTypeGuid = new System.Guid(controllerIconMap.ControllerGuid);
    controllerIdentifier.controllerType = Rewired.ControllerType.Joystick;

    foreach (var mapCategory in Rewired.ReInput.mapping.MapCategories)
    {
    var mapInstance = Rewired.ReInput.mapping.GetControllerTemplateMapInstance(Rewired.GamepadTemplate.typeGuid, mapCategory.id, 0);
    if (mapInstance != null)
    if (controllerIconMap.IconMap.UseTemplateIds)
    {
    var mapInstance = Rewired.ReInput.mapping.GetControllerTemplateMapInstance(Rewired.GamepadTemplate.typeGuid, mapCategory.id, layoutId);
    if (mapInstance != null)
    {
    foreach (var actionElement in mapInstance.ElementMaps)
    {
    if (actionElement.actionId == actionId)
    {
    var inputIcon = controllerIconMap.IconMap.GetInputIcon(actionElement.elementIdentifierId, actionElement.actionId);
    if (inputIcon != null)
    {
    inputIcons.Add(inputIcon);
    }
    }
    }
    }
    }
    else
    {
    foreach (var actionElement in mapInstance.ElementMaps)
    var controllerMap = Rewired.ReInput.mapping.GetControllerMapInstance(controllerIdentifier, mapCategory.id, layoutId);
    if (controllerMap != null)
    {
    if (actionElement.actionId == actionId)
    foreach (var actionElement in controllerMap.AllMaps)
    {
    var inputIcon = controllerMap.IconMap.GetInputIcon(actionElement.elementIdentifierId);
    if (inputIcon != null)
    if (actionElement.actionId == actionId)
    {
    inputIcons.Add(inputIcon);
    var inputIcon = controllerIconMap.IconMap.GetInputIcon(actionElement.elementIdentifierId, actionElement.actionId);
    if (inputIcon != null)
    {
    inputIcons.Add(inputIcon);
    }
    }
    }
    }
    108 changes: 96 additions & 12 deletions InputIconMapDefinition.cs
    Original file line number Diff line number Diff line change
    @@ -14,18 +14,45 @@ public class InputIcon
    public Color IconLabelColor = Color.white;
    public Vector3 IconLabelOffset;
    public bool FlipX;
    public bool DisableMapping;
    }

    [CreateAssetMenu(fileName = "new-input-icon-mapping", menuName = "Input Icon Mapping", order = 0)]
    [CreateAssetMenu(fileName = "new-input-icon-mapping", menuName = "Input Icon Mapping")]
    public class InputIconMapDefinition : ScriptableObject
    {
    public bool UseTemplateIds = true;

    public InputIcon TiltIcon => _tiltIcon;

    [SerializeField, UnityEngine.Serialization.FormerlySerializedAs("inputIcons")]
    private InputIcon[] _inputIcons = null;

    [SerializeField]
    private InputIcon[] inputIcons = null;
    private ActionIconOverride[] _actionIconOverrides = null;

    private List<Rewired.ControllerTemplateElementTarget> _elementTargets = new List<Rewired.ControllerTemplateElementTarget>();
    [SerializeField]
    private InputIcon _tiltIcon = null;

    public InputIcon GetInputIcon(Rewired.ActionElementMap elementMap, Rewired.Controller controller)
    #pragma warning disable CS0414
    [SerializeField]
    private Rewired.Data.Mapping.HardwareJoystickMap _hardwareMap = null;
    #pragma warning restore CS0414

    private static List<Rewired.ControllerTemplateElementTarget> _elementTargets = new List<Rewired.ControllerTemplateElementTarget>();

    [System.Serializable]
    private struct ActionIconOverride
    {
    [Rewired.ActionIdProperty(typeof(RewiredConsts.Action))]
    public int ActionId;

    public InputIcon InputIcon;
    }

    // Get the id of the corresponding input element from the controller's template definition, if it exists
    public static int GetTemplatedInputId(Rewired.ActionElementMap elementMap)
    {
    Rewired.Controller controller = elementMap.controllerMap.controller;
    int inputId = elementMap.elementIdentifierId;
    if (controller.templateCount > 0)
    {
    @@ -37,12 +64,34 @@ public InputIcon GetInputIcon(Rewired.ActionElementMap elementMap, Rewired.Contr
    }
    }

    return inputId;
    }

    public InputIcon GetInputIcon(Rewired.ActionElementMap elementMap, Rewired.Controller controller)
    {
    int inputId = UseTemplateIds ? GetTemplatedInputId(elementMap) : elementMap.elementIdentifierId;
    return GetInputIcon(inputId, elementMap.actionId);
    }

    public InputIcon GetInputIcon(int inputId, int actionId)
    {
    if (_actionIconOverrides != null)
    {
    for (int i = 0; i < _actionIconOverrides.Length; ++i)
    {
    if (_actionIconOverrides[i].ActionId == actionId)
    {
    return _actionIconOverrides[i].InputIcon;
    }
    }
    }

    return GetInputIcon(inputId);
    }

    public InputIcon GetInputIcon(int inputId)
    {
    foreach (InputIcon inputIcon in inputIcons)
    foreach (InputIcon inputIcon in _inputIcons)
    {
    if (inputIcon.InputId == inputId)
    {
    @@ -53,13 +102,48 @@ public InputIcon GetInputIcon(int inputId)
    return null;
    }

    #if UNITY_EDITOR
    [ContextMenu("Load From Hardware Map")]
    private void LoadFromHardwareMap()
    {
    var oldInputIcons = _inputIcons;

    UnityEditor.Undo.RecordObject(this, "Load from hardware map");

    int index = 0;
    _inputIcons = new InputIcon[_hardwareMap.elementIdentifierCount];
    foreach (var elementIdentifier in _hardwareMap.ElementIdentifiers)
    {
    var icon = new InputIcon();
    icon.InputId = elementIdentifier.id;
    icon.Comment = elementIdentifier.name;
    icon.IconColor = Color.white;
    icon.IconLabelColor = Color.white;
    _inputIcons[index] = icon;
    ++index;
    }

    for (int i = 0; i < oldInputIcons.Length && i < _inputIcons.Length; ++i)
    {
    if (oldInputIcons[i].InputId == _inputIcons[i].InputId)
    {
    _inputIcons[i].IconSprite = oldInputIcons[i].IconSprite;
    _inputIcons[i].IconLabel = oldInputIcons[i].IconLabel;
    _inputIcons[i].IconLabelSprite = oldInputIcons[i].IconLabelSprite;
    }
    }

    UnityEditor.EditorUtility.SetDirty(this);
    }
    #endif

    [ContextMenu("Generate Keyboard Map")]
    private void GenerateKeyboardMap()
    {
    Rewired.Keyboard keyboard = Rewired.ReInput.controllers.Keyboard;

    InputIcon firstIcon = inputIcons[0];
    inputIcons = new InputIcon[keyboard.ElementIdentifiers.Count];
    InputIcon firstIcon = _inputIcons[0];
    _inputIcons = new InputIcon[keyboard.ElementIdentifiers.Count];

    for (int i = 0; i < keyboard.ElementIdentifiers.Count; ++i)
    {
    @@ -72,26 +156,26 @@ private void GenerateKeyboardMap()
    keyIcon.Comment = keyElement.name.ToString();
    keyIcon.IconLabel = keyElement.name;
    keyIcon.InputId = keyElement.id;
    inputIcons[i] = keyIcon;
    _inputIcons[i] = keyIcon;
    }
    }

    [ContextMenu("Apply Item 0 Icon Color")]
    private void DebugAdjustColors()
    {
    for (int i = 1; i < inputIcons.Length; ++i)
    for (int i = 1; i < _inputIcons.Length; ++i)
    {
    inputIcons[i].IconColor = inputIcons[0].IconColor;
    _inputIcons[i].IconColor = _inputIcons[0].IconColor;
    }
    }


    [ContextMenu("Apply Item 0 Icon")]
    private void DebugAdjustIcons()
    {
    for (int i = 1; i < inputIcons.Length; ++i)
    for (int i = 1; i < _inputIcons.Length; ++i)
    {
    inputIcons[i].IconSprite = inputIcons[0].IconSprite;
    _inputIcons[i].IconSprite = _inputIcons[0].IconSprite;
    }
    }
    }
  3. phosphoer revised this gist Jul 20, 2022. 2 changed files with 2 additions and 2 deletions.
    2 changes: 1 addition & 1 deletion ControllerIconMapDefinition.cs
    Original file line number Diff line number Diff line change
    @@ -1,7 +1,7 @@
    using UnityEngine;
    using System.Collections.Generic;

    [CreateAssetMenu(fileName = "new-controller-icon-mapping", menuName = "Controller Icon Mapping", order = 0]
    [CreateAssetMenu(fileName = "new-controller-icon-mapping", menuName = "Controller Icon Mapping", order = 0)]
    public class ControllerIconMapDefinition : ScriptableObject
    {
    [SerializeField]
    2 changes: 1 addition & 1 deletion InputIconMapDefinition.cs
    Original file line number Diff line number Diff line change
    @@ -16,7 +16,7 @@ public class InputIcon
    public bool FlipX;
    }

    [CreateAssetMenu(fileName = "new-input-icon-mapping", menuName = "Input Icon Mapping", order = 0]
    [CreateAssetMenu(fileName = "new-input-icon-mapping", menuName = "Input Icon Mapping", order = 0)]
    public class InputIconMapDefinition : ScriptableObject
    {
    [SerializeField]
  4. phosphoer revised this gist Jul 20, 2022. 2 changed files with 2 additions and 2 deletions.
    2 changes: 1 addition & 1 deletion ControllerIconMapDefinition.cs
    Original file line number Diff line number Diff line change
    @@ -1,7 +1,7 @@
    using UnityEngine;
    using System.Collections.Generic;

    [CreateAssetMenu(fileName = "new-controller-icon-mapping", menuName = "Controller Icon Mapping", order = (int)MenuItemOrder.Misc)]
    [CreateAssetMenu(fileName = "new-controller-icon-mapping", menuName = "Controller Icon Mapping", order = 0]
    public class ControllerIconMapDefinition : ScriptableObject
    {
    [SerializeField]
    2 changes: 1 addition & 1 deletion InputIconMapDefinition.cs
    Original file line number Diff line number Diff line change
    @@ -16,7 +16,7 @@ public class InputIcon
    public bool FlipX;
    }

    [CreateAssetMenu(fileName = "new-input-icon-mapping", menuName = "Input Icon Mapping", order = (int)MenuItemOrder.Misc)]
    [CreateAssetMenu(fileName = "new-input-icon-mapping", menuName = "Input Icon Mapping", order = 0]
    public class InputIconMapDefinition : ScriptableObject
    {
    [SerializeField]
  5. phosphoer revised this gist Jul 20, 2022. 2 changed files with 2 additions and 2 deletions.
    2 changes: 1 addition & 1 deletion ControllerIconMapDefinition.cs
    Original file line number Diff line number Diff line change
    @@ -1,7 +1,7 @@
    using UnityEngine;
    using System.Collections.Generic;

    [CreateAssetMenu(fileName = "new-controller-icon-mapping", menuName = "Boat Game/Controller Icon Mapping", order = (int)MenuItemOrder.Misc)]
    [CreateAssetMenu(fileName = "new-controller-icon-mapping", menuName = "Controller Icon Mapping", order = (int)MenuItemOrder.Misc)]
    public class ControllerIconMapDefinition : ScriptableObject
    {
    [SerializeField]
    2 changes: 1 addition & 1 deletion InputIconMapDefinition.cs
    Original file line number Diff line number Diff line change
    @@ -16,7 +16,7 @@ public class InputIcon
    public bool FlipX;
    }

    [CreateAssetMenu(fileName = "new-input-icon-mapping", menuName = "Boat Game/Input Icon Mapping", order = (int)MenuItemOrder.Misc)]
    [CreateAssetMenu(fileName = "new-input-icon-mapping", menuName = "Input Icon Mapping", order = (int)MenuItemOrder.Misc)]
    public class InputIconMapDefinition : ScriptableObject
    {
    [SerializeField]
  6. phosphoer revised this gist Jul 20, 2022. 2 changed files with 228 additions and 23 deletions.
    170 changes: 161 additions & 9 deletions ControllerIconMapDefinition.cs
    Original file line number Diff line number Diff line change
    @@ -1,8 +1,7 @@
    using UnityEngine;
    using UnityEngine.UI;
    using System.Collections.Generic;

    [CreateAssetMenu(fileName = "new-controller-icon-mapping", menuName = "Controller Icon Mapping")]
    [CreateAssetMenu(fileName = "new-controller-icon-mapping", menuName = "Boat Game/Controller Icon Mapping", order = (int)MenuItemOrder.Misc)]
    public class ControllerIconMapDefinition : ScriptableObject
    {
    [SerializeField]
    @@ -14,26 +13,147 @@ public class ControllerIconMapDefinition : ScriptableObject
    [SerializeField]
    private InputIconMapDefinition mouseMap = null;

    private List<Rewired.ControllerTemplateElementTarget> _elementTargets = new List<Rewired.ControllerTemplateElementTarget>();
    [SerializeField]
    private ControllerMapPair[] controllerMaps = null;

    [System.Serializable]
    private class ControllerMapPair
    {
    public string Name = string.Empty;
    public string ControllerGuid = string.Empty;
    public InputIconMapDefinition IconMap = null;
    }

    private static List<Rewired.ControllerTemplateElementTarget> _elementTargets = new List<Rewired.ControllerTemplateElementTarget>();
    private Dictionary<string, InputIconMapDefinition> _controllerIdMap;

    public static void GetElementMapsForAction(int actionId, Rewired.Player player, List<Rewired.ActionElementMap> elementMaps)
    {
    Rewired.Controller lastController = player.controllers.GetLastActiveController();
    foreach (var elementMap in player.controllers.maps.ElementMapsWithAction(lastController, actionId, skipDisabledMaps: false))
    {
    elementMaps.Add(elementMap);
    }
    }

    public static int GetTemplatedInputId(Rewired.ActionElementMap elementMap)
    {
    Rewired.Controller controller = elementMap.controllerMap.controller;

    int inputId = elementMap.elementIdentifierId;
    if (controller.templateCount > 0)
    {
    _elementTargets.Clear();
    controller.Templates[0].GetElementTargets(elementMap, _elementTargets);
    if (_elementTargets.Count > 0)
    {
    inputId = _elementTargets[0].element.id;
    }
    }

    return inputId;
    }

    // Find icons for an input action, based on whatever the current detected controller type is
    public bool GetIconsForAction(int actionId, Rewired.Player player, List<InputIcon> inputIcons)
    {
    // Find out the last controller used
    EnsureControllerMaps();
    Rewired.Controller lastController = player.controllers.GetLastActiveController();
    if (lastController.type == Rewired.ControllerType.Joystick)
    if (lastController == null)
    lastController = GetPlatformDefaultController();

    // Store previous icon count so we can determine whether we successfully found more
    int prevCount = inputIcons.Count;

    // Try to find a specific templated input icon map for this controller
    if (_controllerIdMap.TryGetValue(lastController.hardwareTypeGuid.ToString(), out InputIconMapDefinition specificMap))
    {
    FillInputIcons(inputIcons, gamepadMap, player, lastController, actionId);
    FillInputIcons(inputIcons, specificMap, player, lastController, actionId);
    }
    // Otherwise, fallback to the default generic mappings
    else
    {
    FillInputIcons(inputIcons, keyboardMap, player, Rewired.ReInput.controllers.Keyboard, actionId);
    FillInputIcons(inputIcons, mouseMap, player, Rewired.ReInput.controllers.Mouse, actionId);
    if (lastController.type == Rewired.ControllerType.Joystick)
    {
    FillInputIcons(inputIcons, gamepadMap, player, lastController, actionId);
    }
    else
    {
    FillInputIcons(inputIcons, mouseMap, player, Rewired.ReInput.controllers.Mouse, actionId);
    FillInputIcons(inputIcons, keyboardMap, player, Rewired.ReInput.controllers.Keyboard, actionId);
    }
    }

    return inputIcons.Count > prevCount;
    }

    // Find an icon for a specific input mapping, which is already associated with a controller
    public InputIcon GetIconForInput(Rewired.ActionElementMap elementMap)
    {
    // This is an unassigned action, and therefore can't have any icon
    if (elementMap.controllerMap == null)
    return null;

    // Get info about the input action
    EnsureControllerMaps();
    Rewired.Controller controller = elementMap.controllerMap.controller;
    int templatedId = GetTemplatedInputId(elementMap);
    bool isAxis = elementMap.elementType == Rewired.ControllerElementType.Axis;

    // Try finding a specific controller icon map
    InputIconMapDefinition iconMap = null;
    _controllerIdMap.TryGetValue(controller.hardwareTypeGuid.ToString(), out iconMap);

    // If we didn't find one, fallback to one of the default generic icon maps
    if (iconMap == null)
    {
    if (controller.type == Rewired.ControllerType.Joystick)
    {
    iconMap = gamepadMap;
    }
    else if (controller.type == Rewired.ControllerType.Keyboard)
    {
    iconMap = keyboardMap;
    }
    else if (controller.type == Rewired.ControllerType.Mouse)
    {
    iconMap = mouseMap;
    }
    }

    return iconMap != null ? iconMap.GetInputIcon(templatedId) : null;
    }

    private Rewired.Controller GetPlatformDefaultController()
    {
    // If there's any connected gamepad, use that
    if (Rewired.ReInput.controllers.Joysticks.Count > 0)
    {
    return Rewired.ReInput.controllers.Joysticks[0];
    }

    return inputIcons.Count > 0;
    // Default to the keyboard (this does not affect console)
    return Rewired.ReInput.controllers.Keyboard;
    }

    private void EnsureControllerMaps()
    {
    if (_controllerIdMap == null)
    {
    _controllerIdMap = new Dictionary<string, InputIconMapDefinition>();
    for (int i = 0; i < controllerMaps.Length; ++i)
    {
    ControllerMapPair pair = controllerMaps[i];
    _controllerIdMap[pair.ControllerGuid.ToString()] = pair.IconMap;
    }
    }
    }

    // Fill input icons using the player and a controller
    private void FillInputIcons(List<InputIcon> inputIcons, InputIconMapDefinition iconMap, Rewired.Player player, Rewired.Controller controller, int actionId)
    {
    Rewired.InputAction action = Rewired.ReInput.mapping.GetAction(actionId);
    foreach (var elementMap in player.controllers.maps.ElementMapsWithAction(controller, actionId, skipDisabledMaps: false))
    {
    int inputId = elementMap.elementIdentifierId;
    @@ -42,11 +162,43 @@ private void FillInputIcons(List<InputIcon> inputIcons, InputIconMapDefinition i
    _elementTargets.Clear();
    controller.Templates[0].GetElementTargets(elementMap, _elementTargets);
    if (_elementTargets.Count > 0)
    {
    inputId = _elementTargets[0].element.id;
    }
    }

    // Debug.Log($"Getting icon for inputID {inputId} for action {action.name}");

    var inputIcon = iconMap.GetInputIcon(inputId);
    inputIcons.Add(inputIcon);
    if (inputIcon != null)
    inputIcons.Add(inputIcon);
    else
    Debug.LogWarning($"Failed to get input icon for action {action.name} with input id {inputId}");
    }
    }

    // Fill input icons using just a controller map and an action, with no controller object
    // This uses the default rewired gamepad template which most gamepads implement
    private void FillInputIcons(List<InputIcon> inputIcons, ControllerMapPair controllerMap, int actionId)
    {
    Rewired.InputAction action = Rewired.ReInput.mapping.GetAction(actionId);
    foreach (var mapCategory in Rewired.ReInput.mapping.MapCategories)
    {
    var mapInstance = Rewired.ReInput.mapping.GetControllerTemplateMapInstance(Rewired.GamepadTemplate.typeGuid, mapCategory.id, 0);
    if (mapInstance != null)
    {
    foreach (var actionElement in mapInstance.ElementMaps)
    {
    if (actionElement.actionId == actionId)
    {
    var inputIcon = controllerMap.IconMap.GetInputIcon(actionElement.elementIdentifierId);
    if (inputIcon != null)
    {
    inputIcons.Add(inputIcon);
    }
    }
    }
    }
    }
    }
    }
    81 changes: 67 additions & 14 deletions InputIconMapDefinition.cs
    Original file line number Diff line number Diff line change
    @@ -1,34 +1,45 @@
    using UnityEngine;
    using UnityEngine.UI;
    using System.Collections.Generic;

    [System.Serializable]
    public struct InputIcon
    public class InputIcon
    {
    // A comment to identify this input icon in inspector
    public string Comment;

    // The input ID that this icon represents, maps to Rewired's 'elementIdentifierId'
    public int InputId;

    // The sprite for this icon
    public Sprite IconSprite;

    // An optional label to display on the sprite
    public Color IconColor = Color.white;
    public string IconLabel;

    // Offset from icon center for the label
    public Sprite IconLabelSprite;
    public Color IconLabelColor = Color.white;
    public Vector3 IconLabelOffset;

    // Whether to flip the icon horizontally
    public bool FlipX;
    }

    [CreateAssetMenu(fileName = "new-input-icon-mapping", menuName = "Input Icon Mapping")]
    [CreateAssetMenu(fileName = "new-input-icon-mapping", menuName = "Boat Game/Input Icon Mapping", order = (int)MenuItemOrder.Misc)]
    public class InputIconMapDefinition : ScriptableObject
    {
    [SerializeField]
    private InputIcon[] inputIcons = null;

    private List<Rewired.ControllerTemplateElementTarget> _elementTargets = new List<Rewired.ControllerTemplateElementTarget>();

    public InputIcon GetInputIcon(Rewired.ActionElementMap elementMap, Rewired.Controller controller)
    {
    int inputId = elementMap.elementIdentifierId;
    if (controller.templateCount > 0)
    {
    _elementTargets.Clear();
    controller.Templates[0].GetElementTargets(elementMap, _elementTargets);
    if (_elementTargets.Count > 0)
    {
    inputId = _elementTargets[0].element.id;
    }
    }

    return GetInputIcon(inputId);
    }

    public InputIcon GetInputIcon(int inputId)
    {
    foreach (InputIcon inputIcon in inputIcons)
    @@ -39,6 +50,48 @@ public InputIcon GetInputIcon(int inputId)
    }
    }

    return default(InputIcon);
    return null;
    }

    [ContextMenu("Generate Keyboard Map")]
    private void GenerateKeyboardMap()
    {
    Rewired.Keyboard keyboard = Rewired.ReInput.controllers.Keyboard;

    InputIcon firstIcon = inputIcons[0];
    inputIcons = new InputIcon[keyboard.ElementIdentifiers.Count];

    for (int i = 0; i < keyboard.ElementIdentifiers.Count; ++i)
    {
    var keyElement = keyboard.ElementIdentifiers[i];

    InputIcon keyIcon = new InputIcon();
    keyIcon.IconSprite = firstIcon.IconSprite;
    keyIcon.IconColor = firstIcon.IconColor;
    keyIcon.IconLabelColor = firstIcon.IconLabelColor;
    keyIcon.Comment = keyElement.name.ToString();
    keyIcon.IconLabel = keyElement.name;
    keyIcon.InputId = keyElement.id;
    inputIcons[i] = keyIcon;
    }
    }

    [ContextMenu("Apply Item 0 Icon Color")]
    private void DebugAdjustColors()
    {
    for (int i = 1; i < inputIcons.Length; ++i)
    {
    inputIcons[i].IconColor = inputIcons[0].IconColor;
    }
    }


    [ContextMenu("Apply Item 0 Icon")]
    private void DebugAdjustIcons()
    {
    for (int i = 1; i < inputIcons.Length; ++i)
    {
    inputIcons[i].IconSprite = inputIcons[0].IconSprite;
    }
    }
    }
  7. phosphoer revised this gist Apr 12, 2019. 2 changed files with 2 additions and 2 deletions.
    2 changes: 1 addition & 1 deletion ControllerIconMapDefinition.cs
    Original file line number Diff line number Diff line change
    @@ -2,7 +2,7 @@
    using UnityEngine.UI;
    using System.Collections.Generic;

    [CreateAssetMenu(fileName = "new-controller-icon-mapping", menuName = "Controller Icon Mapping"]
    [CreateAssetMenu(fileName = "new-controller-icon-mapping", menuName = "Controller Icon Mapping")]
    public class ControllerIconMapDefinition : ScriptableObject
    {
    [SerializeField]
    2 changes: 1 addition & 1 deletion InputIconMapDefinition.cs
    Original file line number Diff line number Diff line change
    @@ -23,7 +23,7 @@ public struct InputIcon
    public bool FlipX;
    }

    [CreateAssetMenu(fileName = "new-input-icon-mapping", menuName = "Input Icon Mapping"]
    [CreateAssetMenu(fileName = "new-input-icon-mapping", menuName = "Input Icon Mapping")]
    public class InputIconMapDefinition : ScriptableObject
    {
    [SerializeField]
  8. phosphoer revised this gist Apr 12, 2019. 2 changed files with 2 additions and 2 deletions.
    2 changes: 1 addition & 1 deletion ControllerIconMapDefinition.cs
    Original file line number Diff line number Diff line change
    @@ -2,7 +2,7 @@
    using UnityEngine.UI;
    using System.Collections.Generic;

    [CreateAssetMenu(fileName = "new-controller-icon-mapping", menuName = "Controller Icon Mapping", order = (int)MenuItemOrder.Misc)]
    [CreateAssetMenu(fileName = "new-controller-icon-mapping", menuName = "Controller Icon Mapping"]
    public class ControllerIconMapDefinition : ScriptableObject
    {
    [SerializeField]
    2 changes: 1 addition & 1 deletion InputIconMapDefinition.cs
    Original file line number Diff line number Diff line change
    @@ -23,7 +23,7 @@ public struct InputIcon
    public bool FlipX;
    }

    [CreateAssetMenu(fileName = "new-input-icon-mapping", menuName = "Input Icon Mapping", order = (int)MenuItemOrder.Misc)]
    [CreateAssetMenu(fileName = "new-input-icon-mapping", menuName = "Input Icon Mapping"]
    public class InputIconMapDefinition : ScriptableObject
    {
    [SerializeField]
  9. phosphoer revised this gist Apr 12, 2019. 1 changed file with 0 additions and 1 deletion.
    1 change: 0 additions & 1 deletion ControllerIconMapDefinition.cs
    Original file line number Diff line number Diff line change
    @@ -48,6 +48,5 @@ private void FillInputIcons(List<InputIcon> inputIcons, InputIconMapDefinition i
    var inputIcon = iconMap.GetInputIcon(inputId);
    inputIcons.Add(inputIcon);
    }

    }
    }
  10. phosphoer revised this gist Apr 12, 2019. 1 changed file with 0 additions and 1 deletion.
    1 change: 0 additions & 1 deletion InputIconMapDefinition.cs
    Original file line number Diff line number Diff line change
    @@ -26,7 +26,6 @@ public struct InputIcon
    [CreateAssetMenu(fileName = "new-input-icon-mapping", menuName = "Input Icon Mapping", order = (int)MenuItemOrder.Misc)]
    public class InputIconMapDefinition : ScriptableObject
    {

    [SerializeField]
    private InputIcon[] inputIcons = null;

  11. phosphoer revised this gist Apr 12, 2019. 2 changed files with 2 additions and 2 deletions.
    2 changes: 1 addition & 1 deletion ControllerIconMapDefinition.cs
    Original file line number Diff line number Diff line change
    @@ -2,7 +2,7 @@
    using UnityEngine.UI;
    using System.Collections.Generic;

    [CreateAssetMenu(fileName = "new-controller-icon-mapping", menuName = "Boat Game/Controller Icon Mapping", order = (int)MenuItemOrder.Misc)]
    [CreateAssetMenu(fileName = "new-controller-icon-mapping", menuName = "Controller Icon Mapping", order = (int)MenuItemOrder.Misc)]
    public class ControllerIconMapDefinition : ScriptableObject
    {
    [SerializeField]
    2 changes: 1 addition & 1 deletion InputIconMapDefinition.cs
    Original file line number Diff line number Diff line change
    @@ -23,7 +23,7 @@ public struct InputIcon
    public bool FlipX;
    }

    [CreateAssetMenu(fileName = "new-input-icon-mapping", menuName = "Boat Game/Input Icon Mapping", order = (int)MenuItemOrder.Misc)]
    [CreateAssetMenu(fileName = "new-input-icon-mapping", menuName = "Input Icon Mapping", order = (int)MenuItemOrder.Misc)]
    public class InputIconMapDefinition : ScriptableObject
    {

  12. phosphoer created this gist Apr 12, 2019.
    53 changes: 53 additions & 0 deletions ControllerIconMapDefinition.cs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,53 @@
    using UnityEngine;
    using UnityEngine.UI;
    using System.Collections.Generic;

    [CreateAssetMenu(fileName = "new-controller-icon-mapping", menuName = "Boat Game/Controller Icon Mapping", order = (int)MenuItemOrder.Misc)]
    public class ControllerIconMapDefinition : ScriptableObject
    {
    [SerializeField]
    private InputIconMapDefinition gamepadMap = null;

    [SerializeField]
    private InputIconMapDefinition keyboardMap = null;

    [SerializeField]
    private InputIconMapDefinition mouseMap = null;

    private List<Rewired.ControllerTemplateElementTarget> _elementTargets = new List<Rewired.ControllerTemplateElementTarget>();

    public bool GetIconsForAction(int actionId, Rewired.Player player, List<InputIcon> inputIcons)
    {
    Rewired.Controller lastController = player.controllers.GetLastActiveController();
    if (lastController.type == Rewired.ControllerType.Joystick)
    {
    FillInputIcons(inputIcons, gamepadMap, player, lastController, actionId);
    }
    else
    {
    FillInputIcons(inputIcons, keyboardMap, player, Rewired.ReInput.controllers.Keyboard, actionId);
    FillInputIcons(inputIcons, mouseMap, player, Rewired.ReInput.controllers.Mouse, actionId);
    }

    return inputIcons.Count > 0;
    }

    private void FillInputIcons(List<InputIcon> inputIcons, InputIconMapDefinition iconMap, Rewired.Player player, Rewired.Controller controller, int actionId)
    {
    foreach (var elementMap in player.controllers.maps.ElementMapsWithAction(controller, actionId, skipDisabledMaps: false))
    {
    int inputId = elementMap.elementIdentifierId;
    if (controller.templateCount > 0)
    {
    _elementTargets.Clear();
    controller.Templates[0].GetElementTargets(elementMap, _elementTargets);
    if (_elementTargets.Count > 0)
    inputId = _elementTargets[0].element.id;
    }

    var inputIcon = iconMap.GetInputIcon(inputId);
    inputIcons.Add(inputIcon);
    }

    }
    }
    45 changes: 45 additions & 0 deletions InputIconMapDefinition.cs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,45 @@
    using UnityEngine;
    using UnityEngine.UI;

    [System.Serializable]
    public struct InputIcon
    {
    // A comment to identify this input icon in inspector
    public string Comment;

    // The input ID that this icon represents, maps to Rewired's 'elementIdentifierId'
    public int InputId;

    // The sprite for this icon
    public Sprite IconSprite;

    // An optional label to display on the sprite
    public string IconLabel;

    // Offset from icon center for the label
    public Vector3 IconLabelOffset;

    // Whether to flip the icon horizontally
    public bool FlipX;
    }

    [CreateAssetMenu(fileName = "new-input-icon-mapping", menuName = "Boat Game/Input Icon Mapping", order = (int)MenuItemOrder.Misc)]
    public class InputIconMapDefinition : ScriptableObject
    {

    [SerializeField]
    private InputIcon[] inputIcons = null;

    public InputIcon GetInputIcon(int inputId)
    {
    foreach (InputIcon inputIcon in inputIcons)
    {
    if (inputIcon.InputId == inputId)
    {
    return inputIcon;
    }
    }

    return default(InputIcon);
    }
    }