public static string GenerateWrapperCode(InputActionAsset asset, Options options = new Options()) { if (string.IsNullOrEmpty(options.sourceAssetPath)) { options.sourceAssetPath = AssetDatabase.GetAssetPath(asset); } if (string.IsNullOrEmpty(options.className) && !string.IsNullOrEmpty(asset.name)) { options.className = CSharpCodeHelpers.MakeTypeName(asset.name); } return(GenerateWrapperCode(asset.actionMaps, options)); }
// Generate a string containing C# code that simplifies working with the given // action sets in code. public static string GenerateWrapperCode(IEnumerable <InputActionMap> sets, Options options) { if (string.IsNullOrEmpty(options.sourceAssetPath)) { throw new ArgumentException("options.sourceAssetPath"); } if (string.IsNullOrEmpty(options.className)) { options.className = CSharpCodeHelpers.MakeTypeName(Path.GetFileNameWithoutExtension(options.sourceAssetPath)); } var writer = new Writer { buffer = new StringBuilder() }; // Header. writer.WriteLine(string.Format("// GENERATED AUTOMATICALLY FROM '{0}'\n", options.sourceAssetPath)); // Begin namespace. var haveNamespace = !string.IsNullOrEmpty(options.namespaceName); if (haveNamespace) { writer.WriteLine(string.Format("namespace {0}", options.namespaceName)); writer.BeginBlock(); } // Begin class. writer.WriteLine("[System.Serializable]"); writer.WriteLine(string.Format("public class {0} : UnityEngine.Experimental.Input.InputActionWrapper", options.className)); writer.BeginBlock(); // Initialize method. writer.WriteLine("private bool m_Initialized;"); writer.WriteLine("private void Initialize()"); writer.BeginBlock(); foreach (var set in sets) { var setName = CSharpCodeHelpers.MakeIdentifier(set.name); writer.WriteLine(string.Format("// {0}", set.name)); writer.WriteLine(string.Format("m_{0} = asset.GetActionMap(\"{1}\");", setName, set.name)); foreach (var action in set.actions) { writer.WriteLine(string.Format("m_{0}_{1} = m_{2}.GetAction(\"{3}\");", setName, CSharpCodeHelpers.MakeIdentifier(action.name), setName, action.name)); } } writer.WriteLine("m_Initialized = true;"); writer.EndBlock(); // Action set accessors. foreach (var set in sets) { writer.WriteLine(string.Format("// {0}", set.name)); var setName = CSharpCodeHelpers.MakeIdentifier(set.name); var setStructName = CSharpCodeHelpers.MakeTypeName(setName, "Actions"); // Caching field for action set. writer.WriteLine(string.Format("private UnityEngine.Experimental.Input.InputActionMap m_{0};", setName)); // Caching fields for all actions. foreach (var action in set.actions) { writer.WriteLine(string.Format("private UnityEngine.Experimental.Input.InputAction m_{0}_{1};", setName, CSharpCodeHelpers.MakeIdentifier(action.name))); } // Struct wrapping access to action set. writer.WriteLine(string.Format("public struct {0}", setStructName)); writer.BeginBlock(); // Constructor. writer.WriteLine(string.Format("private {0} m_Wrapper;", options.className)); writer.WriteLine(string.Format("public {0}({1} wrapper) {{ m_Wrapper = wrapper; }}", setStructName, options.className)); // Getter for each action. foreach (var action in set.actions) { var actionName = CSharpCodeHelpers.MakeIdentifier(action.name); writer.WriteLine(string.Format( "public UnityEngine.Experimental.Input.InputAction @{0} {{ get {{ return m_Wrapper.m_{1}_{2}; }} }}", actionName, setName, actionName)); } // Action set getter. writer.WriteLine(string.Format("public UnityEngine.Experimental.Input.InputActionMap Get() {{ return m_Wrapper.m_{0}; }}", setName)); // Enable/disable methods. writer.WriteLine("public void Enable() { Get().Enable(); }"); writer.WriteLine("public void Disable() { Get().Disable(); }"); // Clone method. writer.WriteLine("public UnityEngine.Experimental.Input.InputActionMap Clone() { return Get().Clone(); }"); // Implicit conversion operator. writer.WriteLine(string.Format( "public static implicit operator UnityEngine.Experimental.Input.InputActionMap({0} set) {{ return set.Get(); }}", setStructName)); writer.EndBlock(); // Getter for instance of struct. writer.WriteLine(string.Format("public {0} @{1}", setStructName, setName)); writer.BeginBlock(); writer.WriteLine("get"); writer.BeginBlock(); writer.WriteLine("if (!m_Initialized) Initialize();"); writer.WriteLine(string.Format("return new {0}(this);", setStructName)); writer.EndBlock(); writer.EndBlock(); } // End class. writer.EndBlock(); // End namespace. if (haveNamespace) { writer.EndBlock(); } return(writer.buffer.ToString()); }
// Generate a string containing C# code that simplifies working with the given // action sets in code. public static string GenerateWrapperCode(IEnumerable <InputActionMap> maps, IEnumerable <InputControlScheme> schemes, Options options) { if (string.IsNullOrEmpty(options.sourceAssetPath)) { throw new ArgumentException("options.sourceAssetPath"); } if (string.IsNullOrEmpty(options.className)) { options.className = CSharpCodeHelpers.MakeTypeName(Path.GetFileNameWithoutExtension(options.sourceAssetPath)); } var writer = new Writer { buffer = new StringBuilder() }; // Header. writer.WriteLine(string.Format("// GENERATED AUTOMATICALLY FROM '{0}'\n", options.sourceAssetPath)); // Usings. writer.WriteLine("using System;"); writer.WriteLine("using UnityEngine;"); if (options.generateEvents) { writer.WriteLine("using UnityEngine.Events;"); } writer.WriteLine("using UnityEngine.Experimental.Input;"); writer.WriteLine("\n"); // Begin namespace. var haveNamespace = !string.IsNullOrEmpty(options.namespaceName); if (haveNamespace) { writer.WriteLine(string.Format("namespace {0}", options.namespaceName)); writer.BeginBlock(); } // Begin class. writer.WriteLine("[Serializable]"); writer.WriteLine(string.Format("public class {0} : InputActionAssetReference", options.className)); writer.BeginBlock(); // Default constructor. writer.WriteLine(string.Format("public {0}()", options.className)); writer.BeginBlock(); writer.EndBlock(); // Explicit constructor. writer.WriteLine(string.Format("public {0}(InputActionAsset asset)", options.className)); ++writer.indentLevel; writer.WriteLine(": base(asset)"); --writer.indentLevel; writer.BeginBlock(); writer.EndBlock(); // Initialize method. writer.WriteLine("private bool m_Initialized;"); writer.WriteLine("private void Initialize()"); writer.BeginBlock(); foreach (var set in maps) { var setName = CSharpCodeHelpers.MakeIdentifier(set.name); writer.WriteLine(string.Format("// {0}", set.name)); writer.WriteLine(string.Format("m_{0} = asset.GetActionMap(\"{1}\");", setName, set.name)); foreach (var action in set.actions) { var actionName = CSharpCodeHelpers.MakeIdentifier(action.name); writer.WriteLine(string.Format("m_{0}_{1} = m_{2}.GetAction(\"{3}\");", setName, actionName, setName, action.name)); if (options.generateEvents) { WriteActionEventInitializer(setName, actionName, InputActionPhase.Started, writer); WriteActionEventInitializer(setName, actionName, InputActionPhase.Performed, writer); WriteActionEventInitializer(setName, actionName, InputActionPhase.Cancelled, writer); } } } writer.WriteLine("m_Initialized = true;"); writer.EndBlock(); // Uninitialize method. writer.WriteLine("private void Uninitialize()"); writer.BeginBlock(); foreach (var set in maps) { var setName = CSharpCodeHelpers.MakeIdentifier(set.name); writer.WriteLine(string.Format("m_{0} = null;", setName)); foreach (var action in set.actions) { var actionName = CSharpCodeHelpers.MakeIdentifier(action.name); writer.WriteLine(string.Format("m_{0}_{1} = null;", setName, actionName)); if (options.generateEvents) { WriteActionEventInitializer(setName, actionName, InputActionPhase.Started, writer, removeCallback: true); WriteActionEventInitializer(setName, actionName, InputActionPhase.Performed, writer, removeCallback: true); WriteActionEventInitializer(setName, actionName, InputActionPhase.Cancelled, writer, removeCallback: true); } } } writer.WriteLine("m_Initialized = false;"); writer.EndBlock(); // SwitchAsset method. writer.WriteLine("public void SwitchAsset(InputActionAsset newAsset)"); writer.BeginBlock(); writer.WriteLine("if (newAsset == asset) return;"); writer.WriteLine("if (m_Initialized) Uninitialize();"); writer.WriteLine("asset = newAsset;"); writer.EndBlock(); ////REVIEW: DuplicateActionsAndBindings? // DuplicateAndSwitchAsset method. writer.WriteLine("public void DuplicateAndSwitchAsset()"); writer.BeginBlock(); writer.WriteLine("SwitchAsset(ScriptableObject.Instantiate(asset));"); writer.EndBlock(); // Action map accessors. foreach (var map in maps) { writer.WriteLine(string.Format("// {0}", map.name)); var setName = CSharpCodeHelpers.MakeIdentifier(map.name); var setStructName = CSharpCodeHelpers.MakeTypeName(setName, "Actions"); // Caching field for action set. writer.WriteLine(string.Format("private InputActionMap m_{0};", setName)); // Caching fields for all actions. foreach (var action in map.actions) { var actionName = CSharpCodeHelpers.MakeIdentifier(action.name); writer.WriteLine(string.Format("private InputAction m_{0}_{1};", setName, actionName)); if (options.generateEvents) { WriteActionEventField(setName, actionName, InputActionPhase.Started, writer); WriteActionEventField(setName, actionName, InputActionPhase.Performed, writer); WriteActionEventField(setName, actionName, InputActionPhase.Cancelled, writer); } } // Struct wrapping access to action set. writer.WriteLine(string.Format("public struct {0}", setStructName)); writer.BeginBlock(); // Constructor. writer.WriteLine(string.Format("private {0} m_Wrapper;", options.className)); writer.WriteLine(string.Format("public {0}({1} wrapper) {{ m_Wrapper = wrapper; }}", setStructName, options.className)); // Getter for each action. foreach (var action in map.actions) { var actionName = CSharpCodeHelpers.MakeIdentifier(action.name); writer.WriteLine(string.Format( "public InputAction @{0} {{ get {{ return m_Wrapper.m_{1}_{2}; }} }}", actionName, setName, actionName)); // Action event getters. if (options.generateEvents) { WriteActionEventGetter(setName, actionName, InputActionPhase.Started, writer); WriteActionEventGetter(setName, actionName, InputActionPhase.Performed, writer); WriteActionEventGetter(setName, actionName, InputActionPhase.Cancelled, writer); } } // Action set getter. writer.WriteLine(string.Format("public InputActionMap Get() {{ return m_Wrapper.m_{0}; }}", setName)); // Enable/disable methods. writer.WriteLine("public void Enable() { Get().Enable(); }"); writer.WriteLine("public void Disable() { Get().Disable(); }"); // Clone method. writer.WriteLine("public InputActionMap Clone() { return Get().Clone(); }"); // Implicit conversion operator. writer.WriteLine(string.Format( "public static implicit operator InputActionMap({0} set) {{ return set.Get(); }}", setStructName)); writer.EndBlock(); // Getter for instance of struct. writer.WriteLine(string.Format("public {0} @{1}", setStructName, setName)); writer.BeginBlock(); writer.WriteLine("get"); writer.BeginBlock(); writer.WriteLine("if (!m_Initialized) Initialize();"); writer.WriteLine(string.Format("return new {0}(this);", setStructName)); writer.EndBlock(); writer.EndBlock(); } // Control scheme accessors. foreach (var scheme in schemes) { var identifier = CSharpCodeHelpers.MakeIdentifier(scheme.name); writer.WriteLine(string.Format("private int m_{0}SchemeIndex = -1;", identifier)); writer.WriteLine(string.Format("public InputControlScheme {0}Scheme", identifier)); writer.BeginBlock(); writer.WriteLine("get\n"); writer.BeginBlock(); writer.WriteLine(string.Format( "if (m_{0}SchemeIndex == -1) m_{0}SchemeIndex = asset.GetControlSchemeIndex(\"{1}\");", identifier, scheme.name)); writer.WriteLine(string.Format("return asset.controlSchemes[m_{0}SchemeIndex];", identifier)); writer.EndBlock(); writer.EndBlock(); } // Action event class. if (options.generateEvents) { writer.WriteLine("[Serializable]"); writer.WriteLine("public class ActionEvent : UnityEvent<InputAction.CallbackContext>"); writer.BeginBlock(); writer.EndBlock(); } // End class. writer.EndBlock(); // End namespace. if (haveNamespace) { writer.EndBlock(); } return(writer.buffer.ToString()); }
public override void OnInspectorGUI() { // ScriptedImporterEditor in 2019.2 now requires explicitly updating the SerializedObject // like in other types of editors. serializedObject.Update(); // Button to pop up window to edit the asset. if (GUILayout.Button("Edit asset")) { InputActionEditorWindow.OnOpenAsset(GetAsset().GetInstanceID(), 0); } EditorGUILayout.Space(); // Importer settings UI. var generateWrapperCodeProperty = serializedObject.FindProperty("m_GenerateWrapperCode"); EditorGUILayout.PropertyField(generateWrapperCodeProperty, m_GenerateWrapperCodeLabel); if (generateWrapperCodeProperty.boolValue) { var wrapperCodePathProperty = serializedObject.FindProperty("m_WrapperCodePath"); var wrapperClassNameProperty = serializedObject.FindProperty("m_WrapperClassName"); var wrapperCodeNamespaceProperty = serializedObject.FindProperty("m_WrapperCodeNamespace"); EditorGUILayout.BeginHorizontal(); var assetPath = AssetDatabase.GetAssetPath(GetAsset()); var defaultFileName = Path.ChangeExtension(assetPath, ".cs"); wrapperCodePathProperty.PropertyFieldWithDefaultText(m_WrapperCodePathLabel, defaultFileName); if (GUILayout.Button("…", EditorStyles.miniButton, GUILayout.MaxWidth(20))) { var fileName = EditorUtility.SaveFilePanel("Location for generated C# file", Path.GetDirectoryName(defaultFileName), Path.GetFileName(defaultFileName), "cs"); if (!string.IsNullOrEmpty(fileName)) { if (fileName.StartsWith(Application.dataPath)) { fileName = "Assets/" + fileName.Substring(Application.dataPath.Length + 1); } wrapperCodePathProperty.stringValue = fileName; } } EditorGUILayout.EndHorizontal(); wrapperClassNameProperty.PropertyFieldWithDefaultText(m_WrapperClassNameLabel, CSharpCodeHelpers.MakeTypeName(GetAsset().name)); if (!CSharpCodeHelpers.IsEmptyOrProperIdentifier(wrapperClassNameProperty.stringValue)) { EditorGUILayout.HelpBox("Must be a valid C# identifier", MessageType.Error); } wrapperCodeNamespaceProperty.PropertyFieldWithDefaultText(m_WrapperCodeNamespaceLabel, "<Global namespace>"); if (!CSharpCodeHelpers.IsEmptyOrProperNamespaceName(wrapperCodeNamespaceProperty.stringValue)) { EditorGUILayout.HelpBox("Must be a valid C# namespace name", MessageType.Error); } } // Using ApplyRevertGUI requires calling Update and ApplyModifiedProperties around the serializedObject, // and will print warning messages otherwise (see warning message in ApplyRevertGUI implementation). serializedObject.ApplyModifiedProperties(); ApplyRevertGUI(); }
public static string GenerateWrapperCode(InputActionAsset asset, Options options = new Options()) { if (asset == null) { throw new ArgumentNullException(nameof(asset)); } if (string.IsNullOrEmpty(options.sourceAssetPath)) { options.sourceAssetPath = AssetDatabase.GetAssetPath(asset); } if (string.IsNullOrEmpty(options.className) && !string.IsNullOrEmpty(asset.name)) { options.className = CSharpCodeHelpers.MakeTypeName(asset.name); } if (string.IsNullOrEmpty(options.className)) { if (string.IsNullOrEmpty(options.sourceAssetPath)) { throw new ArgumentException("options.sourceAssetPath"); } options.className = CSharpCodeHelpers.MakeTypeName(Path.GetFileNameWithoutExtension(options.sourceAssetPath)); } var writer = new Writer { buffer = new StringBuilder() }; // Header. if (!string.IsNullOrEmpty(options.sourceAssetPath)) { writer.WriteLine($"// GENERATED AUTOMATICALLY FROM '{options.sourceAssetPath}'\n"); } // Usings. writer.WriteLine("using System.Collections;"); writer.WriteLine("using System.Collections.Generic;"); writer.WriteLine("using UnityEngine.InputSystem;"); writer.WriteLine("using UnityEngine.InputSystem.Utilities;"); writer.WriteLine(""); // Begin namespace. var haveNamespace = !string.IsNullOrEmpty(options.namespaceName); if (haveNamespace) { writer.WriteLine($"namespace {options.namespaceName}"); writer.BeginBlock(); } // Begin class. writer.WriteLine($"public class {options.className} : IInputActionCollection"); writer.BeginBlock(); writer.WriteLine($"private InputActionAsset asset;"); // Default constructor. writer.WriteLine($"public {options.className}()"); writer.BeginBlock(); writer.WriteLine($"asset = InputActionAsset.FromJson(@\"{asset.ToJson().Replace("\"", "\"\"")}\");"); var maps = asset.actionMaps; var schemes = asset.controlSchemes; foreach (var map in maps) { var mapName = CSharpCodeHelpers.MakeIdentifier(map.name); writer.WriteLine($"// {map.name}"); writer.WriteLine($"m_{mapName} = asset.FindActionMap(\"{map.name}\", throwIfNotFound: true);"); foreach (var action in map.actions) { var actionName = CSharpCodeHelpers.MakeIdentifier(action.name); writer.WriteLine($"m_{mapName}_{actionName} = m_{mapName}.FindAction(\"{action.name}\", throwIfNotFound: true);"); } } writer.EndBlock(); writer.WriteLine(); writer.WriteLine($"~{options.className}()"); writer.BeginBlock(); writer.WriteLine("UnityEngine.Object.Destroy(asset);"); writer.EndBlock(); writer.WriteLine(); writer.WriteLine("public InputBinding? bindingMask"); writer.BeginBlock(); writer.WriteLine("get => asset.bindingMask;"); writer.WriteLine("set => asset.bindingMask = value;"); writer.EndBlock(); writer.WriteLine(); writer.WriteLine("public ReadOnlyArray<InputDevice>? devices"); writer.BeginBlock(); writer.WriteLine("get => asset.devices;"); writer.WriteLine("set => asset.devices = value;"); writer.EndBlock(); writer.WriteLine(); writer.WriteLine("public ReadOnlyArray<InputControlScheme> controlSchemes => asset.controlSchemes;"); writer.WriteLine(); writer.WriteLine("public bool Contains(InputAction action)"); writer.BeginBlock(); writer.WriteLine("return asset.Contains(action);"); writer.EndBlock(); writer.WriteLine(); writer.WriteLine("public IEnumerator<InputAction> GetEnumerator()"); writer.BeginBlock(); writer.WriteLine("return asset.GetEnumerator();"); writer.EndBlock(); writer.WriteLine(); writer.WriteLine("IEnumerator IEnumerable.GetEnumerator()"); writer.BeginBlock(); writer.WriteLine("return GetEnumerator();"); writer.EndBlock(); writer.WriteLine(); writer.WriteLine("public void Enable()"); writer.BeginBlock(); writer.WriteLine("asset.Enable();"); writer.EndBlock(); writer.WriteLine(); writer.WriteLine("public void Disable()"); writer.BeginBlock(); writer.WriteLine("asset.Disable();"); writer.EndBlock(); // Action map accessors. foreach (var map in maps) { writer.WriteLine(); writer.WriteLine($"// {map.name}"); var mapName = CSharpCodeHelpers.MakeIdentifier(map.name); var mapTypeName = CSharpCodeHelpers.MakeTypeName(mapName, "Actions"); // Caching field for action map. writer.WriteLine($"private readonly InputActionMap m_{mapName};"); writer.WriteLine(string.Format("private I{0} m_{0}CallbackInterface;", mapTypeName)); // Caching fields for all actions. foreach (var action in map.actions) { var actionName = CSharpCodeHelpers.MakeIdentifier(action.name); writer.WriteLine($"private readonly InputAction m_{mapName}_{actionName};"); } // Struct wrapping access to action set. writer.WriteLine($"public struct {mapTypeName}"); writer.BeginBlock(); // Constructor. writer.WriteLine($"private {options.className} m_Wrapper;"); writer.WriteLine($"public {mapTypeName}({options.className} wrapper) {{ m_Wrapper = wrapper; }}"); // Getter for each action. foreach (var action in map.actions) { var actionName = CSharpCodeHelpers.MakeIdentifier(action.name); writer.WriteLine( $"public InputAction @{actionName} => m_Wrapper.m_{mapName}_{actionName};"); } // Action map getter. writer.WriteLine($"public InputActionMap Get() {{ return m_Wrapper.m_{mapName}; }}"); // Enable/disable methods. writer.WriteLine("public void Enable() { Get().Enable(); }"); writer.WriteLine("public void Disable() { Get().Disable(); }"); writer.WriteLine("public bool enabled => Get().enabled;"); // Implicit conversion operator. writer.WriteLine( $"public static implicit operator InputActionMap({mapTypeName} set) {{ return set.Get(); }}"); // SetCallbacks method. writer.WriteLine($"public void SetCallbacks(I{mapTypeName} instance)"); writer.BeginBlock(); ////REVIEW: this would benefit from having a single callback on InputActions rather than three different endpoints // Uninitialize existing interface. writer.WriteLine($"if (m_Wrapper.m_{mapTypeName}CallbackInterface != null)"); writer.BeginBlock(); foreach (var action in map.actions) { var actionName = CSharpCodeHelpers.MakeIdentifier(action.name); var actionTypeName = CSharpCodeHelpers.MakeTypeName(action.name); writer.WriteLine($"{actionName}.started -= m_Wrapper.m_{mapTypeName}CallbackInterface.On{actionTypeName};"); writer.WriteLine($"{actionName}.performed -= m_Wrapper.m_{mapTypeName}CallbackInterface.On{actionTypeName};"); writer.WriteLine($"{actionName}.canceled -= m_Wrapper.m_{mapTypeName}CallbackInterface.On{actionTypeName};"); } writer.EndBlock(); // Initialize new interface. writer.WriteLine($"m_Wrapper.m_{mapTypeName}CallbackInterface = instance;"); writer.WriteLine("if (instance != null)"); writer.BeginBlock(); foreach (var action in map.actions) { var actionName = CSharpCodeHelpers.MakeIdentifier(action.name); var actionTypeName = CSharpCodeHelpers.MakeTypeName(action.name); writer.WriteLine($"{actionName}.started += instance.On{actionTypeName};"); writer.WriteLine($"{actionName}.performed += instance.On{actionTypeName};"); writer.WriteLine($"{actionName}.canceled += instance.On{actionTypeName};"); } writer.EndBlock(); writer.EndBlock(); writer.EndBlock(); // Getter for instance of struct. writer.WriteLine($"public {mapTypeName} @{mapName} => new {mapTypeName}(this);"); } // Control scheme accessors. foreach (var scheme in schemes) { var identifier = CSharpCodeHelpers.MakeIdentifier(scheme.name); writer.WriteLine($"private int m_{identifier}SchemeIndex = -1;"); writer.WriteLine($"public InputControlScheme {identifier}Scheme"); writer.BeginBlock(); writer.WriteLine("get"); writer.BeginBlock(); writer.WriteLine($"if (m_{identifier}SchemeIndex == -1) m_{identifier}SchemeIndex = asset.FindControlSchemeIndex(\"{scheme.name}\");"); writer.WriteLine($"return asset.controlSchemes[m_{identifier}SchemeIndex];"); writer.EndBlock(); writer.EndBlock(); } // Generate interfaces. foreach (var map in maps) { var typeName = CSharpCodeHelpers.MakeTypeName(map.name); writer.WriteLine($"public interface I{typeName}Actions"); writer.BeginBlock(); foreach (var action in map.actions) { var methodName = CSharpCodeHelpers.MakeTypeName(action.name); writer.WriteLine($"void On{methodName}(InputAction.CallbackContext context);"); } writer.EndBlock(); } // End class. writer.EndBlock(); // End namespace. if (haveNamespace) { writer.EndBlock(); } return(writer.buffer.ToString()); }
private void OnNotificationBehaviorChange() { Debug.Assert(m_ActionAssetInitialized); serializedObject.ApplyModifiedProperties(); var notificationBehavior = (PlayerNotifications)m_NotificationBehaviorProperty.intValue; switch (notificationBehavior) { // Create text that lists all the messages sent by the component. case PlayerNotifications.BroadcastMessages: case PlayerNotifications.SendMessages: { var builder = new StringBuilder(); builder.Append("Will "); if (notificationBehavior == PlayerNotifications.BroadcastMessages) { builder.Append("BroadcastMessage()"); } else { builder.Append("SendMessage()"); } builder.Append(" to GameObject: "); builder.Append(PlayerInput.DeviceLostMessage); builder.Append(", "); builder.Append(PlayerInput.DeviceRegainedMessage); builder.Append(", "); builder.Append(PlayerInput.ControlsChangedMessage); var playerInput = (PlayerInput)target; var asset = playerInput.m_Actions; if (asset != null) { foreach (var action in asset) { builder.Append(", On"); builder.Append(CSharpCodeHelpers.MakeTypeName(action.name)); } } m_SendMessagesHelpText = new GUIContent(builder.ToString()); break; } case PlayerNotifications.InvokeUnityEvents: { var playerInput = (PlayerInput)target; if (playerInput.m_DeviceLostEvent == null) { playerInput.m_DeviceLostEvent = new PlayerInput.DeviceLostEvent(); } if (playerInput.m_DeviceRegainedEvent == null) { playerInput.m_DeviceRegainedEvent = new PlayerInput.DeviceRegainedEvent(); } if (playerInput.m_ControlsChangedEvent == null) { playerInput.m_ControlsChangedEvent = new PlayerInput.ControlsChangedEvent(); } serializedObject.Update(); // Force action refresh. m_ActionAssetInitialized = false; Refresh(); break; } } m_NotificationBehaviorInitialized = true; }
// Generate a string containing C# code that simplifies working with the given // action sets in code. public static string GenerateWrapperCode(IEnumerable <InputActionMap> maps, IEnumerable <InputControlScheme> schemes, Options options) { if (string.IsNullOrEmpty(options.className)) { if (string.IsNullOrEmpty(options.sourceAssetPath)) { throw new ArgumentException("options.sourceAssetPath"); } options.className = CSharpCodeHelpers.MakeTypeName(Path.GetFileNameWithoutExtension(options.sourceAssetPath)); } var writer = new Writer { buffer = new StringBuilder() }; // Header. if (!string.IsNullOrEmpty(options.sourceAssetPath)) { writer.WriteLine($"// GENERATED AUTOMATICALLY FROM '{options.sourceAssetPath}'\n"); } // Usings. writer.WriteLine("using System;"); writer.WriteLine("using UnityEngine;"); if (options.generateEvents) { writer.WriteLine("using UnityEngine.Events;"); } writer.WriteLine("using UnityEngine.Experimental.Input;"); writer.WriteLine("\n"); // Begin namespace. var haveNamespace = !string.IsNullOrEmpty(options.namespaceName); if (haveNamespace) { writer.WriteLine($"namespace {options.namespaceName}"); writer.BeginBlock(); } // Begin class. writer.WriteLine("[Serializable]"); writer.WriteLine($"public class {options.className} : InputActionAssetReference"); writer.BeginBlock(); // Default constructor. writer.WriteLine($"public {options.className}()"); writer.BeginBlock(); writer.EndBlock(); // Explicit constructor. writer.WriteLine($"public {options.className}(InputActionAsset asset)"); ++writer.indentLevel; writer.WriteLine(": base(asset)"); --writer.indentLevel; writer.BeginBlock(); writer.EndBlock(); // Initialize method. writer.WriteLine("[NonSerialized] private bool m_Initialized;"); writer.WriteLine("private void Initialize()"); writer.BeginBlock(); foreach (var set in maps) { var setName = CSharpCodeHelpers.MakeIdentifier(set.name); writer.WriteLine($"// {set.name}"); writer.WriteLine($"m_{setName} = asset.GetActionMap(\"{set.name}\");"); foreach (var action in set.actions) { var actionName = CSharpCodeHelpers.MakeIdentifier(action.name); writer.WriteLine($"m_{setName}_{actionName} = m_{setName}.GetAction(\"{action.name}\");"); if (options.generateEvents) { WriteActionEventInitializer(setName, actionName, InputActionPhase.Started, writer); WriteActionEventInitializer(setName, actionName, InputActionPhase.Performed, writer); WriteActionEventInitializer(setName, actionName, InputActionPhase.Cancelled, writer); } } } writer.WriteLine("m_Initialized = true;"); writer.EndBlock(); // Uninitialize method. writer.WriteLine("private void Uninitialize()"); writer.BeginBlock(); foreach (var map in maps) { var mapName = CSharpCodeHelpers.MakeIdentifier(map.name); if (options.generateInterfaces) { var mapTypeName = CSharpCodeHelpers.MakeTypeName(map.name, "Actions"); writer.WriteLine($"if (m_{mapTypeName}CallbackInterface != null)"); writer.BeginBlock(); writer.WriteLine($"{mapName}.SetCallbacks(null);"); writer.EndBlock(); } writer.WriteLine($"m_{mapName} = null;"); foreach (var action in map.actions) { var actionName = CSharpCodeHelpers.MakeIdentifier(action.name); writer.WriteLine($"m_{mapName}_{actionName} = null;"); if (options.generateEvents) { WriteActionEventInitializer(mapName, actionName, InputActionPhase.Started, writer, removeCallback: true); WriteActionEventInitializer(mapName, actionName, InputActionPhase.Performed, writer, removeCallback: true); WriteActionEventInitializer(mapName, actionName, InputActionPhase.Cancelled, writer, removeCallback: true); } } } writer.WriteLine("m_Initialized = false;"); writer.EndBlock(); // SwitchAsset method. writer.WriteLine("public void SetAsset(InputActionAsset newAsset)"); writer.BeginBlock(); writer.WriteLine("if (newAsset == asset) return;"); if (options.generateInterfaces) { foreach (var map in maps) { var mapName = CSharpCodeHelpers.MakeIdentifier(map.name); var mapTypeName = CSharpCodeHelpers.MakeTypeName(map.name, "Actions"); writer.WriteLine($"var {mapName}Callbacks = m_{mapTypeName}CallbackInterface;"); } } writer.WriteLine("if (m_Initialized) Uninitialize();"); writer.WriteLine("asset = newAsset;"); if (options.generateInterfaces) { foreach (var map in maps) { var mapName = CSharpCodeHelpers.MakeIdentifier(map.name); writer.WriteLine(string.Format("{0}.SetCallbacks({0}Callbacks);", mapName)); } } writer.EndBlock(); // MakePrivateCopyOfActions method. writer.WriteLine("public override void MakePrivateCopyOfActions()"); writer.BeginBlock(); writer.WriteLine("SetAsset(ScriptableObject.Instantiate(asset));"); writer.EndBlock(); // Action map accessors. foreach (var map in maps) { writer.WriteLine($"// {map.name}"); var mapName = CSharpCodeHelpers.MakeIdentifier(map.name); var mapTypeName = CSharpCodeHelpers.MakeTypeName(mapName, "Actions"); // Caching field for action map. writer.WriteLine($"private InputActionMap m_{mapName};"); if (options.generateInterfaces) { writer.WriteLine(string.Format("private I{0} m_{0}CallbackInterface;", mapTypeName)); } // Caching fields for all actions. foreach (var action in map.actions) { var actionName = CSharpCodeHelpers.MakeIdentifier(action.name); writer.WriteLine($"private InputAction m_{mapName}_{actionName};"); if (options.generateEvents) { WriteActionEventField(mapName, actionName, InputActionPhase.Started, writer); WriteActionEventField(mapName, actionName, InputActionPhase.Performed, writer); WriteActionEventField(mapName, actionName, InputActionPhase.Cancelled, writer); } } // Struct wrapping access to action set. writer.WriteLine($"public struct {mapTypeName}"); writer.BeginBlock(); // Constructor. writer.WriteLine($"private {options.className} m_Wrapper;"); writer.WriteLine($"public {mapTypeName}({options.className} wrapper) {{ m_Wrapper = wrapper; }}"); // Getter for each action. foreach (var action in map.actions) { var actionName = CSharpCodeHelpers.MakeIdentifier(action.name); writer.WriteLine( $"public InputAction @{actionName} {{ get {{ return m_Wrapper.m_{mapName}_{actionName}; }} }}"); // Action event getters. if (options.generateEvents) { WriteActionEventGetter(mapName, actionName, InputActionPhase.Started, writer); WriteActionEventGetter(mapName, actionName, InputActionPhase.Performed, writer); WriteActionEventGetter(mapName, actionName, InputActionPhase.Cancelled, writer); } } // Action map getter. writer.WriteLine($"public InputActionMap Get() {{ return m_Wrapper.m_{mapName}; }}"); // Enable/disable methods. writer.WriteLine("public void Enable() { Get().Enable(); }"); writer.WriteLine("public void Disable() { Get().Disable(); }"); writer.WriteLine("public bool enabled { get { return Get().enabled; } }"); // Clone method. writer.WriteLine("public InputActionMap Clone() { return Get().Clone(); }"); // Implicit conversion operator. writer.WriteLine( $"public static implicit operator InputActionMap({mapTypeName} set) {{ return set.Get(); }}"); // SetCallbacks method. if (options.generateInterfaces) { writer.WriteLine($"public void SetCallbacks(I{mapTypeName} instance)"); writer.BeginBlock(); ////REVIEW: this would benefit from having a single callback on InputActions rather than three different endpoints // Uninitialize existing interface. writer.WriteLine($"if (m_Wrapper.m_{mapTypeName}CallbackInterface != null)"); writer.BeginBlock(); foreach (var action in map.actions) { var actionName = CSharpCodeHelpers.MakeIdentifier(action.name); var actionTypeName = CSharpCodeHelpers.MakeTypeName(action.name); writer.WriteLine($"{actionName}.started -= m_Wrapper.m_{mapTypeName}CallbackInterface.On{actionTypeName};"); writer.WriteLine($"{actionName}.performed -= m_Wrapper.m_{mapTypeName}CallbackInterface.On{actionTypeName};"); writer.WriteLine($"{actionName}.cancelled -= m_Wrapper.m_{mapTypeName}CallbackInterface.On{actionTypeName};"); } writer.EndBlock(); // Initialize new interface. writer.WriteLine($"m_Wrapper.m_{mapTypeName}CallbackInterface = instance;"); writer.WriteLine("if (instance != null)"); writer.BeginBlock(); foreach (var action in map.actions) { var actionName = CSharpCodeHelpers.MakeIdentifier(action.name); var actionTypeName = CSharpCodeHelpers.MakeTypeName(action.name); writer.WriteLine($"{actionName}.started += instance.On{actionTypeName};"); writer.WriteLine($"{actionName}.performed += instance.On{actionTypeName};"); writer.WriteLine($"{actionName}.cancelled += instance.On{actionTypeName};"); } writer.EndBlock(); writer.EndBlock(); } writer.EndBlock(); // Getter for instance of struct. writer.WriteLine($"public {mapTypeName} @{mapName}"); writer.BeginBlock(); writer.WriteLine("get"); writer.BeginBlock(); writer.WriteLine("if (!m_Initialized) Initialize();"); writer.WriteLine($"return new {mapTypeName}(this);"); writer.EndBlock(); writer.EndBlock(); } // Control scheme accessors. foreach (var scheme in schemes) { var identifier = CSharpCodeHelpers.MakeIdentifier(scheme.name); writer.WriteLine($"private int m_{identifier}SchemeIndex = -1;"); writer.WriteLine($"public InputControlScheme {identifier}Scheme"); writer.BeginBlock(); writer.WriteLine("get\n"); writer.BeginBlock(); writer.WriteLine($"if (m_{identifier}SchemeIndex == -1) m_{identifier}SchemeIndex = asset.GetControlSchemeIndex(\"{scheme.name}\");"); writer.WriteLine($"return asset.controlSchemes[m_{identifier}SchemeIndex];"); writer.EndBlock(); writer.EndBlock(); } // Action event class. if (options.generateEvents) { writer.WriteLine("[Serializable]"); writer.WriteLine("public class ActionEvent : UnityEvent<InputAction.CallbackContext>"); writer.BeginBlock(); writer.EndBlock(); } // End class. writer.EndBlock(); // Generate interfaces. if (options.generateInterfaces) { foreach (var map in maps) { var typeName = CSharpCodeHelpers.MakeTypeName(map.name); writer.WriteLine($"public interface I{typeName}Actions"); writer.BeginBlock(); foreach (var action in map.actions) { var methodName = CSharpCodeHelpers.MakeTypeName(action.name); writer.WriteLine($"void On{methodName}(InputAction.CallbackContext context);"); } writer.EndBlock(); } } // End namespace. if (haveNamespace) { writer.EndBlock(); } return(writer.buffer.ToString()); }