Handle multiple controller input layouts?

I’ve been looking around for an answer about how to handle multiple controller input layouts, and all the answers I’ve seen suggest making a separate layout for each controller. The answers are also pretty old (a few years) and I’m wondering if there’s a better new method of handling this?

Some controllers use Axis for D-pad, others use buttons, so far all I am left with is hard-coding for each controller type, and that is just a pain, as not all controllers have the same button mapping/axis mapping etc.

I can’t have a menu to remap controls either (as far as I know) for Android without putting the user through hassle.

Any suggestions would be greatly appreciated :slight_smile:

The best option I know of is to use a different Input Manager than the default unity manager, such as Input Manager.

You might also consider implementing several managers as instances of a ScriptableObject, which would allow you to change default mappings based on the controller ID.

Here’s one way you could implement it (The interface is the same as UnityEngine.Input):

[Serializable]
public class AxesMapping
{
    public string axisName;
    public string inputManagerAxis;
}

public class CustomInput : ScriptableObject
{
    /// <summary>
    /// The default custom input is simply a pass-through
    /// </summary>
    static CustomInput currentCustomInput;
    public static CustomInput CurrentCustomInput
    {
        get
        {
            currentCustomInput = currentCustomInput
                ?? ScriptableObject.CreateInstance<CustomInput>();

            return currentCustomInput;
        }
        set
        {
            currentCustomInput = value;
        }
    }

    #region Inspector Properties
    public string[] controllerIDList = { };
    public AxesMapping[] axesMappings = { };
    #endregion Inspector Properties

    /// <summary>
    /// Parsing a dictionary of mappings is faster than parsing an array, so this should
    /// be used instead of the axesMappings field.
    /// </summary>
    Dictionary<string, string> mappedAxes;
    protected Dictionary<string, string> MappedAxes
    {
        get
        {
            mappedAxes = mappedAxes
                ?? axesMappings.ToDictionary(am => am.axisName, am => am.inputManagerAxis);
            return mappedAxes;
        }
    }

    #region "Overridden" UnityEngine.Input methods
    //
    // Summary:
    //     ///
    //     Returns the value of the virtual axis identified by axisName.
    //     ///
    //
    // Parameters:
    //   axisName:
    public static float GetAxis(string axisName)
    {
        string mappedAxis;
        if (CurrentCustomInput.MappedAxes.TryGetValue(axisName, out mappedAxis))
        {
            return Input.GetAxis(mappedAxis);
        }

        return Input.GetAxis(axisName);
    }

    //////////////////////////
    // Implement all other UnityEngine.Input methods and properties
    //////////////////////////
    #endregion "Overridden" UnityEngine.Input methods
}