Skip to content

Instantly share code, notes, and snippets.

@JISyed
Created April 14, 2017 01:50
Show Gist options
  • Save JISyed/cf27ca0c82a692ae2318ba0f569178f7 to your computer and use it in GitHub Desktop.
Save JISyed/cf27ca0c82a692ae2318ba0f569178f7 to your computer and use it in GitHub Desktop.
Technique to clone Unity's InputManager into a ScripableObject in order to extract data for use in code
using UnityEngine;
using UnityEditor;
namespace XboxCtrlrInput.Editor
{
/// <summary>
/// Clones Unity's Input Manager into a new file at /Assets/Plugins/InputManagerClone.asset
/// </summary>
/// <remarks>
/// Do NOT modify!!!
/// Credit to Leslie Young (http://plyoung.appspot.com/blog/manipulating-input-manager-in-script.html)
/// </remarks>
public static class InputManagerCloner
{
/// <summary>
/// Runs through all the child objects and return the one that matches the given name
/// </summary>
private static SerializedProperty GetChildProperty(SerializedProperty parent, string name)
{
SerializedProperty child = parent.Copy();
child.Next(true);
do
{
if (child.name == name) return child;
}
while (child.Next(false));
return null;
}
[MenuItem("Window/XboxCtrlrInput/Clone Input Manager")]
public static void CloneInputManager()
{
// Make the new blank instance for the InputManager Clone
XciInputManagerClone inputManagerClone = ScriptableObject.CreateInstance<XciInputManagerClone>();
// Retrieve the data of the original InputManager
SerializedObject originalInputManager = new SerializedObject(AssetDatabase.LoadAllAssetsAtPath("ProjectSettings/InputManager.asset")[0]);
SerializedProperty originalInputEntriesCollection = originalInputManager.FindProperty("m_Axes");
// Find the number of entries in the InputManager and allocate space in the clone
int NumOfEntries = originalInputEntriesCollection.arraySize;
inputManagerClone.Alloc(NumOfEntries);
// Loop through every input entry and copy them into the clone
InputManagerEntry currentEntry = null;
SerializedProperty originalEntry = null;
for(int i = 0; i < NumOfEntries; ++i)
{
originalEntry = originalInputEntriesCollection.GetArrayElementAtIndex(i);
currentEntry = inputManagerClone[i];
currentEntry.name = InputManagerCloner.GetChildProperty(originalEntry, "m_Name").stringValue;
currentEntry.descriptiveName = InputManagerCloner.GetChildProperty(originalEntry, "descriptiveName").stringValue;
currentEntry.descriptiveNegativeName = InputManagerCloner.GetChildProperty(originalEntry, "descriptiveNegativeName").stringValue;
currentEntry.negativeButton = InputManagerCloner.GetChildProperty(originalEntry, "negativeButton").stringValue;
currentEntry.positiveButton = InputManagerCloner.GetChildProperty(originalEntry, "positiveButton").stringValue;
currentEntry.altNegativeButton = InputManagerCloner.GetChildProperty(originalEntry, "altNegativeButton").stringValue;
currentEntry.altPositiveButton = InputManagerCloner.GetChildProperty(originalEntry, "altPositiveButton").stringValue;
currentEntry.gravity = InputManagerCloner.GetChildProperty(originalEntry, "gravity").floatValue;
currentEntry.dead = InputManagerCloner.GetChildProperty(originalEntry, "dead").floatValue;
currentEntry.sensitivity = InputManagerCloner.GetChildProperty(originalEntry, "sensitivity").floatValue;
currentEntry.snap = InputManagerCloner.GetChildProperty(originalEntry, "snap").boolValue;
currentEntry.invert = InputManagerCloner.GetChildProperty(originalEntry, "invert").boolValue;
currentEntry.type = (InputManagerEntry.Type) InputManagerCloner.GetChildProperty(originalEntry, "type").intValue;
currentEntry.axis = InputManagerCloner.GetChildProperty(originalEntry, "axis").intValue;
currentEntry.joyNum = InputManagerCloner.GetChildProperty(originalEntry, "joyNum").intValue;
}
// Now save the Input Manager clone to file
// Hard-coded path (always replaces what was originally there) (Do NOT change!)
string finalAssetPath = "Assets/Resources/XboxCtrlrInput/InputManagerClone.asset";
// Create a new data asset into a file on the chosen path
AssetDatabase.CreateAsset(inputManagerClone, finalAssetPath);
// Save and Focus
AssetDatabase.SaveAssets();
}
}
}
using UnityEngine;
namespace XboxCtrlrInput
{
/// <summary>
/// Contains deadzone data of every axis for every joystick number (see XboxController enum).
/// Mostly for use with XInput (Windows API)
/// </summary>
public class XciAxisDeadzoneData
{
private float[] leftStickX = new float[5];
private float[] leftStickY = new float[5];
private float[] rightStickX = new float[5];
private float[] rightStickY = new float[5];
private float[] leftTrigger = new float[5];
private float[] rightTrigger = new float[5];
public void Init(XciInputManagerClone inputManager)
{
this.leftStickX[0] = inputManager.SearchInputByName("XboxAxisXJoy0").dead;
this.leftStickX[1] = inputManager.SearchInputByName("XboxAxisXJoy1").dead;
this.leftStickX[2] = inputManager.SearchInputByName("XboxAxisXJoy2").dead;
this.leftStickX[3] = inputManager.SearchInputByName("XboxAxisXJoy3").dead;
this.leftStickX[4] = inputManager.SearchInputByName("XboxAxisXJoy4").dead;
this.leftStickY[0] = inputManager.SearchInputByName("XboxAxisYJoy0").dead;
this.leftStickY[1] = inputManager.SearchInputByName("XboxAxisYJoy1").dead;
this.leftStickY[2] = inputManager.SearchInputByName("XboxAxisYJoy2").dead;
this.leftStickY[3] = inputManager.SearchInputByName("XboxAxisYJoy3").dead;
this.leftStickY[4] = inputManager.SearchInputByName("XboxAxisYJoy4").dead;
this.rightStickX[0] = inputManager.SearchInputByName("XboxAxis4Joy0").dead;
this.rightStickX[1] = inputManager.SearchInputByName("XboxAxis4Joy1").dead;
this.rightStickX[2] = inputManager.SearchInputByName("XboxAxis4Joy2").dead;
this.rightStickX[3] = inputManager.SearchInputByName("XboxAxis4Joy3").dead;
this.rightStickX[4] = inputManager.SearchInputByName("XboxAxis4Joy4").dead;
this.rightStickY[0] = inputManager.SearchInputByName("XboxAxis5Joy0").dead;
this.rightStickY[1] = inputManager.SearchInputByName("XboxAxis5Joy1").dead;
this.rightStickY[2] = inputManager.SearchInputByName("XboxAxis5Joy2").dead;
this.rightStickY[3] = inputManager.SearchInputByName("XboxAxis5Joy3").dead;
this.rightStickY[4] = inputManager.SearchInputByName("XboxAxis5Joy4").dead;
this.leftTrigger[0] = inputManager.SearchInputByName("XboxAxis3Joy0").dead;
this.leftTrigger[1] = inputManager.SearchInputByName("XboxAxis3Joy1").dead;
this.leftTrigger[2] = inputManager.SearchInputByName("XboxAxis3Joy2").dead;
this.leftTrigger[3] = inputManager.SearchInputByName("XboxAxis3Joy3").dead;
this.leftTrigger[4] = inputManager.SearchInputByName("XboxAxis3Joy4").dead;
this.rightTrigger[0] = inputManager.SearchInputByName("XboxAxis3Joy0").dead;
this.rightTrigger[1] = inputManager.SearchInputByName("XboxAxis3Joy1").dead;
this.rightTrigger[2] = inputManager.SearchInputByName("XboxAxis3Joy2").dead;
this.rightTrigger[3] = inputManager.SearchInputByName("XboxAxis3Joy3").dead;
this.rightTrigger[4] = inputManager.SearchInputByName("XboxAxis3Joy4").dead;
}
public float[] LeftStickX
{
get
{
return this.leftStickX;
}
}
public float[] LeftStickY
{
get
{
return this.leftStickY;
}
}
public float[] RightStickX
{
get
{
return this.rightStickX;
}
}
public float[] RightStickY
{
get
{
return this.rightStickY;
}
}
public float[] LeftTrigger
{
get
{
return this.leftTrigger;
}
}
public float[] RightTrigger
{
get
{
return this.rightTrigger;
}
}
}
}
using UnityEngine;
namespace XboxCtrlrInput
{
/// <summary>
/// An entry of XciInputManagerClone
/// </summary>
/// <remarks>
/// Credit to Leslie Young (http://plyoung.appspot.com/blog/manipulating-input-manager-in-script.html)
/// </remarks>
[System.Serializable]
public class InputManagerEntry
{
public enum Type
{
KeyOrMouseButton = 0,
MouseMovement = 1,
JoystickAxis = 2
}
[SerializeField] public string name;
[SerializeField] public string descriptiveName;
[SerializeField] public string descriptiveNegativeName;
[SerializeField] public string negativeButton;
[SerializeField] public string positiveButton;
[SerializeField] public string altNegativeButton;
[SerializeField] public string altPositiveButton;
[SerializeField] public float gravity;
[SerializeField] public float dead;
[SerializeField] public float sensitivity;
[SerializeField] public bool snap = false;
[SerializeField] public bool invert = false;
[SerializeField] public InputManagerEntry.Type type;
[SerializeField] public int axis;
[SerializeField] public int joyNum;
}
/// <summary>
/// A clone of the Unity Input Manager for reading axis data
/// </summary>
[System.Serializable]
public class XciInputManagerClone : ScriptableObject
{
[SerializeField] private InputManagerEntry[] inputManagerEntries;
public int NumberOfEntries
{
get
{
if(this.inputManagerEntries == null)
{
return -1;
}
return this.inputManagerEntries.Length;
}
}
public InputManagerEntry this[int index]
{
get
{
return this.inputManagerEntries[index];
}
}
/// <summary>
/// Searchs by the name of the input.
/// </summary>
public InputManagerEntry SearchInputByName(string entryName)
{
InputManagerEntry foundEntry = null;
InputManagerEntry currentEntry = null;
int numEntries = this.NumberOfEntries;
for(int i = 0; i < numEntries; i++)
{
currentEntry = this.inputManagerEntries[i];
if(currentEntry.name.Equals(entryName))
{
foundEntry = currentEntry;
break;
}
}
return foundEntry;
}
/// <summary>
/// WARNING: Clears entire Input Manager Clone
/// </summary>
public void Alloc(int numberOfEntries)
{
this.inputManagerEntries = new InputManagerEntry[numberOfEntries];
for(int i = 0; i < numberOfEntries; i++)
{
this.inputManagerEntries[i] = new InputManagerEntry();
}
}
}
}
using UnityEngine;
namespace XboxCtrlrInput
{
/// <summary>
/// Singeton script used by XCI to access a clone of the InputManager at run-time
/// </summary>
public class XciInputManagerReader : MonoBehaviour
{
[SerializeField] private XciInputManagerClone inputManager;
private static XciInputManagerReader instance = null;
void Awake()
{
if(XciInputManagerReader.instance != null)
{
GameObject.Destroy(this.gameObject);
}
XciInputManagerReader.instance = this;
// Load the InputManagerClone
this.inputManager = Resources.Load<XciInputManagerClone>("XboxCtrlrInput/InputManagerClone");
// Lives for the life of the game
DontDestroyOnLoad(this.gameObject);
}
// Use this for initialization
void Start ()
{
}
public XciInputManagerClone InputManager
{
get
{
return this.inputManager;
}
}
public static XciInputManagerReader Instance
{
get
{
if(XciInputManagerReader.instance == null)
{
GameObject xciInputManReaderObj = new GameObject("XboxCtrlrInput Input Manager Reader");
xciInputManReaderObj.AddComponent<XciInputManagerReader>();
}
return XciInputManagerReader.instance;
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment