From eef570b9d05435779cb1f336dd4e56d915a2818d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ha=CC=8Akan=20Sidenvall?= Date: Wed, 21 Aug 2024 14:29:32 +0200 Subject: [PATCH 01/10] Initial draft for code setup analytics --- .../Tests/InputSystem/CoreTests_Analytics.cs | 7 + .../Actions/InputActionSetupExtensions.cs | 49 +++++++ .../InputActionCodeAuthoringAnalytic.cs | 138 ++++++++++++++++++ .../InputActionCodeAuthoringAnalytic.cs.meta | 3 + .../InputActionsEditorSessionAnalytic.cs | 2 +- .../Editor/Analytics/InputBuildAnalytic.cs | 2 +- .../Analytics/InputComponentEditorAnalytic.cs | 4 +- .../Editor/Analytics/InputEditorAnalytics.cs | 2 +- .../Analytics/OnScreenStickEditorAnalytic.cs | 4 +- .../Analytics/PlayerInputEditorAnalytic.cs | 2 +- .../PlayerInputManagerEditorAnalytic.cs | 2 +- .../VirtualMouseInputEditorAnalytic.cs | 2 +- 12 files changed, 207 insertions(+), 10 deletions(-) create mode 100644 Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/InputActionCodeAuthoringAnalytic.cs create mode 100644 Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/InputActionCodeAuthoringAnalytic.cs.meta diff --git a/Assets/Tests/InputSystem/CoreTests_Analytics.cs b/Assets/Tests/InputSystem/CoreTests_Analytics.cs index ef86b4fa64..e652de926b 100644 --- a/Assets/Tests/InputSystem/CoreTests_Analytics.cs +++ b/Assets/Tests/InputSystem/CoreTests_Analytics.cs @@ -663,6 +663,13 @@ public void Analytics_ShouldReportPlayerInputManagerData() } } + [Test] + [Category("Analytics")] + public void Analytics_ShouldReportCodeAuthoringAnalytic() + { + + } + #if UNITY_INPUT_SYSTEM_ENABLE_UI [Test] [Category("Analytics")] diff --git a/Packages/com.unity.inputsystem/InputSystem/Actions/InputActionSetupExtensions.cs b/Packages/com.unity.inputsystem/InputSystem/Actions/InputActionSetupExtensions.cs index f5b087565d..08fb37bcf7 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Actions/InputActionSetupExtensions.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Actions/InputActionSetupExtensions.cs @@ -1,4 +1,5 @@ using System; +using System.Diagnostics; using UnityEngine.InputSystem.Layouts; using UnityEngine.InputSystem.Utilities; @@ -8,6 +9,14 @@ namespace UnityEngine.InputSystem { + internal class InputApiAnalyticCounters + { + private int addActionMapToAsset; + private int removeActionMapFromAsset; + private int addActionToMap; + private int removeActionFromMap; + } + /// /// Methods to change the setup of , , /// and objects. @@ -305,6 +314,21 @@ public static BindingSyntax AddBinding(this InputAction action, string path, str groups = groups }); } + + /// + /// Conditionally compiled helper for logging API usage of code-authored actions. + /// + /// The associated API function. + /// + /// Be extremely carefully to review for indirect calls and overloads to not register analytics twice. + /// Be extremely careful in enabling/disabling tracking before internal calls since those may otherwise + /// be incorrectly registered. + /// + [Conditional("UNITY_EDITOR"), Conditional("UNITY_ANALYTICS"), Conditional("ENABLE_CLOUD_SERVICES_ANALYTICS")] + private static void RegisterApiUsage(UnityEngine.InputSystem.Editor.InputActionCodeAuthoringAnalytic.Api api) + { + UnityEngine.InputSystem.Editor.InputActionCodeAuthoringAnalytic.Register(api); + } /// /// Add a binding that references the given and triggers @@ -349,6 +373,8 @@ public static BindingSyntax AddBinding(this InputAction action, InputControl con /// public static BindingSyntax AddBinding(this InputAction action, InputBinding binding = default) { + RegisterApiUsage(UnityEngine.InputSystem.Editor.InputActionCodeAuthoringAnalytic.Api.AddBinding); + if (action == null) throw new ArgumentNullException(nameof(action)); @@ -478,6 +504,8 @@ public static BindingSyntax AddBinding(this InputActionMap actionMap, string pat /// public static BindingSyntax AddBinding(this InputActionMap actionMap, InputBinding binding) { + RegisterApiUsage(UnityEngine.InputSystem.Editor.InputActionCodeAuthoringAnalytic.Api.AddBinding); + if (actionMap == null) throw new ArgumentNullException(nameof(actionMap)); if (binding.path == null) @@ -501,6 +529,8 @@ public static BindingSyntax AddBinding(this InputActionMap actionMap, InputBindi public static CompositeSyntax AddCompositeBinding(this InputAction action, string composite, string interactions = null, string processors = null) { + RegisterApiUsage(UnityEngine.InputSystem.Editor.InputActionCodeAuthoringAnalytic.Api.AddCompositeBinding); + if (action == null) throw new ArgumentNullException(nameof(action)); if (string.IsNullOrEmpty(composite)) @@ -580,6 +610,8 @@ private static int AddBindingInternal(InputActionMap map, InputBinding binding, /// of ). public static BindingSyntax ChangeBinding(this InputAction action, int index) { + RegisterApiUsage(UnityEngine.InputSystem.Editor.InputActionCodeAuthoringAnalytic.Api.ChangeBinding); + if (action == null) throw new ArgumentNullException(nameof(action)); @@ -638,6 +670,8 @@ public static BindingSyntax ChangeBinding(this InputAction action, string name) /// of ). public static BindingSyntax ChangeBinding(this InputActionMap actionMap, int index) { + RegisterApiUsage(UnityEngine.InputSystem.Editor.InputActionCodeAuthoringAnalytic.Api.ChangeBinding); + if (actionMap == null) throw new ArgumentNullException(nameof(actionMap)); if (index < 0 || index >= actionMap.m_Bindings.LengthSafe()) @@ -836,6 +870,8 @@ public static BindingSyntax ChangeBinding(this InputAction action, InputBinding /// public static BindingSyntax ChangeCompositeBinding(this InputAction action, string compositeName) { + RegisterApiUsage(UnityEngine.InputSystem.Editor.InputActionCodeAuthoringAnalytic.Api.ChangeCompositeBinding); + if (action == null) throw new ArgumentNullException(nameof(action)); if (string.IsNullOrEmpty(compositeName)) @@ -877,6 +913,8 @@ public static BindingSyntax ChangeCompositeBinding(this InputAction action, stri /// public static void Rename(this InputAction action, string newName) { + RegisterApiUsage(UnityEngine.InputSystem.Editor.InputActionCodeAuthoringAnalytic.Api.Rename); + if (action == null) throw new ArgumentNullException(nameof(action)); if (string.IsNullOrEmpty(newName)) @@ -919,6 +957,8 @@ public static void Rename(this InputAction action, string newName) /// public static void AddControlScheme(this InputActionAsset asset, InputControlScheme controlScheme) { + RegisterApiUsage(UnityEngine.InputSystem.Editor.InputActionCodeAuthoringAnalytic.Api.AddControlScheme); + if (asset == null) throw new ArgumentNullException(nameof(asset)); if (string.IsNullOrEmpty(controlScheme.name)) @@ -987,6 +1027,8 @@ public static ControlSchemeSyntax AddControlScheme(this InputActionAsset asset, /// public static void RemoveControlScheme(this InputActionAsset asset, string name) { + RegisterApiUsage(UnityEngine.InputSystem.Editor.InputActionCodeAuthoringAnalytic.Api.RemoveControlScheme); + if (asset == null) throw new ArgumentNullException(nameof(asset)); if (string.IsNullOrEmpty(name)) @@ -1007,11 +1049,14 @@ public static void RemoveControlScheme(this InputActionAsset asset, string name) /// public static InputControlScheme WithBindingGroup(this InputControlScheme scheme, string bindingGroup) { + RegisterApiUsage(UnityEngine.InputSystem.Editor.InputActionCodeAuthoringAnalytic.Api.ControlSchemeWithBindingGroup); + return new ControlSchemeSyntax(scheme).WithBindingGroup(bindingGroup).Done(); } public static InputControlScheme WithDevice(this InputControlScheme scheme, string controlPath, bool required) { + RegisterApiUsage(UnityEngine.InputSystem.Editor.InputActionCodeAuthoringAnalytic.Api.ControlSchemeWithDevice); if (required) return new ControlSchemeSyntax(scheme).WithRequiredDevice(controlPath).Done(); return new ControlSchemeSyntax(scheme).WithOptionalDevice(controlPath).Done(); @@ -1019,21 +1064,25 @@ public static InputControlScheme WithDevice(this InputControlScheme scheme, stri public static InputControlScheme WithRequiredDevice(this InputControlScheme scheme, string controlPath) { + RegisterApiUsage(UnityEngine.InputSystem.Editor.InputActionCodeAuthoringAnalytic.Api.ControlSchemeWithRequiredDevice); return new ControlSchemeSyntax(scheme).WithRequiredDevice(controlPath).Done(); } public static InputControlScheme WithOptionalDevice(this InputControlScheme scheme, string controlPath) { + RegisterApiUsage(UnityEngine.InputSystem.Editor.InputActionCodeAuthoringAnalytic.Api.ControlSchemeWithOptionalDevice); return new ControlSchemeSyntax(scheme).WithOptionalDevice(controlPath).Done(); } public static InputControlScheme OrWithRequiredDevice(this InputControlScheme scheme, string controlPath) { + RegisterApiUsage(UnityEngine.InputSystem.Editor.InputActionCodeAuthoringAnalytic.Api.ControlSchemeOrWithRequiredDevice); return new ControlSchemeSyntax(scheme).OrWithRequiredDevice(controlPath).Done(); } public static InputControlScheme OrWithOptionalDevice(this InputControlScheme scheme, string controlPath) { + RegisterApiUsage(UnityEngine.InputSystem.Editor.InputActionCodeAuthoringAnalytic.Api.ControlSchemeOrWithOptionalDevice); return new ControlSchemeSyntax(scheme).OrWithOptionalDevice(controlPath).Done(); } diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/InputActionCodeAuthoringAnalytic.cs b/Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/InputActionCodeAuthoringAnalytic.cs new file mode 100644 index 0000000000..5d624fe10c --- /dev/null +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/InputActionCodeAuthoringAnalytic.cs @@ -0,0 +1,138 @@ +#if UNITY_EDITOR + +using System; +using UnityEditor; + +namespace UnityEngine.InputSystem.Editor +{ +#if UNITY_2023_2_OR_NEWER + [UnityEngine.Analytics.AnalyticInfo(eventName: kEventName, maxEventsPerHour: kMaxEventsPerHour, + maxNumberOfElements: kMaxNumberOfElements, vendorKey: UnityEngine.InputSystem.InputAnalytics.kVendorKey)] +#endif // UNITY_2023_2_OR_NEWER + internal class InputActionCodeAuthoringAnalytic : UnityEngine.InputSystem.InputAnalytics.IInputAnalytic + { + private const string kEventName = "input_code_authoring"; + private const int kMaxEventsPerHour = 100; // default: 1000 + private const int kMaxNumberOfElements = 100; // default: 1000 + + /// + /// Enumeration type for code authoring APIs mapping to . + /// + /// + /// This enumeration type may be added to, but NEVER changed, since it would break older data. + /// + public enum Api + { + AddBinding = 0, + AddCompositeBinding = 1, + ChangeBinding = 2, + ChangeCompositeBinding = 3, + Rename = 4, + AddControlScheme = 5, + RemoveControlScheme = 6, + ControlSchemeWithBindingGroup = 7, + ControlSchemeWithDevice = 8, + ControlSchemeWithRequiredDevice = 9, + ControlSchemeWithOptionalDevice = 10, + ControlSchemeOrWithRequiredDevice = 11, + ControlSchemeOrWithOptionalDevice = 12 + } + + private static readonly int[] m_Counters = new int[Enum.GetNames(typeof(Api)).Length]; + + public static void Register(Api api) + { + // Note: Currently discards detailed information and only sets a boolean (aggregated) value. + ++m_Counters[(int)api]; + } + + // Cache callback + private static readonly Action PlayModeChanged = OnPlayModeStateChange; + + private static void OnPlayModeStateChange(PlayModeStateChange change) + { + Debug.Log("Play mode state change: " + change); + if (change == PlayModeStateChange.ExitingEditMode) + { + for (var i = 0; i < m_Counters.Length; ++i) + m_Counters[i] = 0; + } + if (change == PlayModeStateChange.ExitingPlayMode) + { + EditorApplication.playModeStateChanged -= PlayModeChanged; + new InputActionCodeAuthoringAnalytic().Send(); + } + } + + [InitializeOnEnterPlayMode] + private static void Hook() + { + EditorApplication.playModeStateChanged -= PlayModeChanged; + EditorApplication.playModeStateChanged += PlayModeChanged; + } + + public InputActionCodeAuthoringAnalytic() + { + info = new InputAnalytics.InputAnalyticInfo(kEventName, kMaxEventsPerHour, kMaxNumberOfElements); + } + + /// + /// Represents InputAction code authoring editor data. + /// + /// + /// Ideally this struct should be readonly but then Unity cannot serialize/deserialize it. + /// + [Serializable] + public struct Data : UnityEngine.InputSystem.InputAnalytics.IInputAnalyticData + { + /// + /// Creates a new Data instance. + /// + /// Specifies whether code authoring has been used. + public Data(bool usesCodeAuthoring) + { + this.usesCodeAuthoring = usesCodeAuthoring; + } + + /// + /// Defines the associated component. + /// + public bool usesCodeAuthoring; + } + +#if UNITY_2023_2_OR_NEWER + public bool TryGatherData(out UnityEngine.Analytics.IAnalytic.IData data, out Exception error) +#else + public bool TryGatherData(out InputAnalytics.IInputAnalyticData data, out Exception error) +#endif + { + try + { + // Determine aggregated perspective, i.e. was any API used + var usedCodeAuthoringDuringPlayMode = false; + for (var i = 0; i < m_Counters.Length; ++i) + { + if (m_Counters[i] > 0) + { + usedCodeAuthoringDuringPlayMode = true; + break; + } + } + + data = new Data(usedCodeAuthoringDuringPlayMode); + error = null; + return true; + } + catch (Exception e) + { + data = null; + error = e; + return false; + } + } + + public InputAnalytics.InputAnalyticInfo info { get; } + } +} + +#endif // UNITY_EDITOR \ No newline at end of file diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/InputActionCodeAuthoringAnalytic.cs.meta b/Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/InputActionCodeAuthoringAnalytic.cs.meta new file mode 100644 index 0000000000..dd7700a303 --- /dev/null +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/InputActionCodeAuthoringAnalytic.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 07c4c48bac384a9e91c29c2f04328c0b +timeCreated: 1724231031 \ No newline at end of file diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/InputActionsEditorSessionAnalytic.cs b/Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/InputActionsEditorSessionAnalytic.cs index 2733dd0fca..a966aa18a0 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/InputActionsEditorSessionAnalytic.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/InputActionsEditorSessionAnalytic.cs @@ -178,7 +178,7 @@ public void End() #region IInputAnalytic Interface -#if UNITY_EDITOR && UNITY_2023_2_OR_NEWER +#if UNITY_2023_2_OR_NEWER public bool TryGatherData(out UnityEngine.Analytics.IAnalytic.IData data, out Exception error) #else public bool TryGatherData(out InputAnalytics.IInputAnalyticData data, out Exception error) diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/InputBuildAnalytic.cs b/Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/InputBuildAnalytic.cs index e2860d398e..40bb709409 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/InputBuildAnalytic.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/InputBuildAnalytic.cs @@ -31,7 +31,7 @@ public InputBuildAnalytic(BuildReport buildReport) public InputAnalytics.InputAnalyticInfo info => new InputAnalytics.InputAnalyticInfo(kEventName, kMaxEventsPerHour, kMaxNumberOfElements); -#if UNITY_EDITOR && UNITY_2023_2_OR_NEWER +#if UNITY_2023_2_OR_NEWER public bool TryGatherData(out UnityEngine.Analytics.IAnalytic.IData data, out Exception error) #else public bool TryGatherData(out InputAnalytics.IInputAnalyticData data, out Exception error) diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/InputComponentEditorAnalytic.cs b/Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/InputComponentEditorAnalytic.cs index d559e7618c..93aef1a521 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/InputComponentEditorAnalytic.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/InputComponentEditorAnalytic.cs @@ -72,7 +72,7 @@ public InputComponentEditorAnalytic(InputSystemComponent component) m_Component = component; } -#if UNITY_EDITOR && UNITY_2023_2_OR_NEWER +#if UNITY_2023_2_OR_NEWER public bool TryGatherData(out UnityEngine.Analytics.IAnalytic.IData data, out Exception error) #else public bool TryGatherData(out InputAnalytics.IInputAnalyticData data, out Exception error) @@ -86,4 +86,4 @@ public bool TryGatherData(out InputAnalytics.IInputAnalyticData data, out Except public InputAnalytics.InputAnalyticInfo info { get; } } } -#endif +#endif // UNITY_EDITOR diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/InputEditorAnalytics.cs b/Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/InputEditorAnalytics.cs index 60bc676df3..a96861b7d2 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/InputEditorAnalytics.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/InputEditorAnalytics.cs @@ -4,7 +4,7 @@ namespace UnityEngine.InputSystem.Editor { - internal static partial class InputEditorAnalytics + internal static class InputEditorAnalytics { /// /// Represents notification behavior setting associated with and diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/OnScreenStickEditorAnalytic.cs b/Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/OnScreenStickEditorAnalytic.cs index 964ef9173a..73ad50e788 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/OnScreenStickEditorAnalytic.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/OnScreenStickEditorAnalytic.cs @@ -66,7 +66,7 @@ public OnScreenStickEditorAnalytic(UnityEditor.Editor editor) m_Editor = editor; } -#if UNITY_EDITOR && UNITY_2023_2_OR_NEWER +#if UNITY_2023_2_OR_NEWER public bool TryGatherData(out UnityEngine.Analytics.IAnalytic.IData data, out Exception error) #else public bool TryGatherData(out InputAnalytics.IInputAnalyticData data, out Exception error) @@ -89,4 +89,4 @@ public bool TryGatherData(out InputAnalytics.IInputAnalyticData data, out Except new InputAnalytics.InputAnalyticInfo(kEventName, kMaxEventsPerHour, kMaxNumberOfElements); } } -#endif +#endif // UNITY_EDITOR diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/PlayerInputEditorAnalytic.cs b/Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/PlayerInputEditorAnalytic.cs index 4520d2eb61..9a821b7f51 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/PlayerInputEditorAnalytic.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/PlayerInputEditorAnalytic.cs @@ -26,7 +26,7 @@ public PlayerInputEditorAnalytic(UnityEditor.Editor editor) public InputAnalytics.InputAnalyticInfo info => new InputAnalytics.InputAnalyticInfo(kEventName, kMaxEventsPerHour, kMaxNumberOfElements); -#if UNITY_EDITOR && UNITY_2023_2_OR_NEWER +#if UNITY_2023_2_OR_NEWER public bool TryGatherData(out UnityEngine.Analytics.IAnalytic.IData data, out Exception error) #else public bool TryGatherData(out InputAnalytics.IInputAnalyticData data, out Exception error) diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/PlayerInputManagerEditorAnalytic.cs b/Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/PlayerInputManagerEditorAnalytic.cs index 77656d2f02..782152fc76 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/PlayerInputManagerEditorAnalytic.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/PlayerInputManagerEditorAnalytic.cs @@ -23,7 +23,7 @@ public PlayerInputManagerEditorAnalytic(UnityEditor.Editor editor) m_Editor = editor; } -#if UNITY_EDITOR && UNITY_2023_2_OR_NEWER +#if UNITY_2023_2_OR_NEWER public bool TryGatherData(out UnityEngine.Analytics.IAnalytic.IData data, out Exception error) #else public bool TryGatherData(out InputAnalytics.IInputAnalyticData data, out Exception error) diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/VirtualMouseInputEditorAnalytic.cs b/Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/VirtualMouseInputEditorAnalytic.cs index a3c6c8e13e..6f1ab38610 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/VirtualMouseInputEditorAnalytic.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/VirtualMouseInputEditorAnalytic.cs @@ -72,7 +72,7 @@ public VirtualMouseInputEditorAnalytic(UnityEditor.Editor editor) m_Editor = editor; } -#if UNITY_EDITOR && UNITY_2023_2_OR_NEWER +#if UNITY_2023_2_OR_NEWER public bool TryGatherData(out UnityEngine.Analytics.IAnalytic.IData data, out Exception error) #else public bool TryGatherData(out InputAnalytics.IInputAnalyticData data, out Exception error) From fc20b219fb976094572b7e766599d482bab6585b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ha=CC=8Akan=20Sidenvall?= Date: Thu, 12 Sep 2024 08:42:12 +0200 Subject: [PATCH 02/10] Updated CHANGELOG --- Packages/com.unity.inputsystem/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Packages/com.unity.inputsystem/CHANGELOG.md b/Packages/com.unity.inputsystem/CHANGELOG.md index 7690c8cde2..1678be23be 100644 --- a/Packages/com.unity.inputsystem/CHANGELOG.md +++ b/Packages/com.unity.inputsystem/CHANGELOG.md @@ -31,6 +31,7 @@ however, it has to be formatted properly to pass verification tests. - Added tests for Input Action Editor UI for managing action maps (List, create, rename, delete) (ISX-2087) - Added automatic loading of custom extensions of InputProcessor, InputInteraction and InputBindingComposite [ISXB-856]](https://issuetracker.unity3d.com/product/unity/issues/guid/ISXB-856). - Added an IME Input sample scene. +- Added analytics for programmatic `InputAction` setup via `InputActionSetupExtensions`. ## [1.10.0] - 2024-07-24 From 5ffe6b7596082f28eb673e6daadae478e5423e71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ha=CC=8Akan=20Sidenvall?= Date: Thu, 12 Sep 2024 08:58:01 +0200 Subject: [PATCH 03/10] Code clean-up --- .../Actions/InputActionSetupExtensions.cs | 10 +--------- .../InputActionCodeAuthoringAnalytic.cs | 16 ++++++++++------ 2 files changed, 11 insertions(+), 15 deletions(-) diff --git a/Packages/com.unity.inputsystem/InputSystem/Actions/InputActionSetupExtensions.cs b/Packages/com.unity.inputsystem/InputSystem/Actions/InputActionSetupExtensions.cs index 08fb37bcf7..5408533341 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Actions/InputActionSetupExtensions.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Actions/InputActionSetupExtensions.cs @@ -9,14 +9,6 @@ namespace UnityEngine.InputSystem { - internal class InputApiAnalyticCounters - { - private int addActionMapToAsset; - private int removeActionMapFromAsset; - private int addActionToMap; - private int removeActionFromMap; - } - /// /// Methods to change the setup of , , /// and objects. @@ -324,7 +316,7 @@ public static BindingSyntax AddBinding(this InputAction action, string path, str /// Be extremely careful in enabling/disabling tracking before internal calls since those may otherwise /// be incorrectly registered. /// - [Conditional("UNITY_EDITOR"), Conditional("UNITY_ANALYTICS"), Conditional("ENABLE_CLOUD_SERVICES_ANALYTICS")] + [Conditional("UNITY_EDITOR")] private static void RegisterApiUsage(UnityEngine.InputSystem.Editor.InputActionCodeAuthoringAnalytic.Api api) { UnityEngine.InputSystem.Editor.InputActionCodeAuthoringAnalytic.Register(api); diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/InputActionCodeAuthoringAnalytic.cs b/Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/InputActionCodeAuthoringAnalytic.cs index 5d624fe10c..bbc6369ad1 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/InputActionCodeAuthoringAnalytic.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/InputActionCodeAuthoringAnalytic.cs @@ -11,7 +11,7 @@ namespace UnityEngine.InputSystem.Editor #endif // UNITY_2023_2_OR_NEWER internal class InputActionCodeAuthoringAnalytic : UnityEngine.InputSystem.InputAnalytics.IInputAnalytic { - private const string kEventName = "input_code_authoring"; + private const string kEventName = "input_action_code_authoring"; private const int kMaxEventsPerHour = 100; // default: 1000 private const int kMaxNumberOfElements = 100; // default: 1000 @@ -46,7 +46,7 @@ public static void Register(Api api) ++m_Counters[(int)api]; } - // Cache callback + // Cache delegate private static readonly Action PlayModeChanged = OnPlayModeStateChange; private static void OnPlayModeStateChange(PlayModeStateChange change) @@ -54,11 +54,13 @@ private static void OnPlayModeStateChange(PlayModeStateChange change) Debug.Log("Play mode state change: " + change); if (change == PlayModeStateChange.ExitingEditMode) { + // Reset all counters when exiting edit mode for (var i = 0; i < m_Counters.Length; ++i) m_Counters[i] = 0; } if (change == PlayModeStateChange.ExitingPlayMode) { + // Send analytics and unhook delegate when exiting play-mode EditorApplication.playModeStateChanged -= PlayModeChanged; new InputActionCodeAuthoringAnalytic().Send(); } @@ -67,11 +69,12 @@ private static void OnPlayModeStateChange(PlayModeStateChange change) [InitializeOnEnterPlayMode] private static void Hook() { + // Make sure only a single play-mode change delegate is registered EditorApplication.playModeStateChanged -= PlayModeChanged; EditorApplication.playModeStateChanged += PlayModeChanged; } - - public InputActionCodeAuthoringAnalytic() + + private InputActionCodeAuthoringAnalytic() { info = new InputAnalytics.InputAnalyticInfo(kEventName, kMaxEventsPerHour, kMaxNumberOfElements); } @@ -95,7 +98,8 @@ public Data(bool usesCodeAuthoring) } /// - /// Defines the associated component. + /// Specifies whether code-authoring (Input Action setup via extensions) was used at least once + /// during play-mode. /// public bool usesCodeAuthoring; } @@ -108,7 +112,7 @@ public bool TryGatherData(out InputAnalytics.IInputAnalyticData data, out Except { try { - // Determine aggregated perspective, i.e. was any API used + // Determine aggregated perspective, i.e. was "any" code-authoring API used var usedCodeAuthoringDuringPlayMode = false; for (var i = 0; i < m_Counters.Length; ++i) { From b4dc342d0f9b2c9dec44010273cb4f71340dafe7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ha=CC=8Akan=20Sidenvall?= Date: Thu, 12 Sep 2024 09:07:24 +0200 Subject: [PATCH 04/10] Added missing compilation guards --- .../Actions/InputActionSetupExtensions.cs | 39 ++++++++++++++++++- .../InputActionCodeAuthoringAnalytic.cs | 6 +-- 2 files changed, 40 insertions(+), 5 deletions(-) diff --git a/Packages/com.unity.inputsystem/InputSystem/Actions/InputActionSetupExtensions.cs b/Packages/com.unity.inputsystem/InputSystem/Actions/InputActionSetupExtensions.cs index 5408533341..0ff2c20964 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Actions/InputActionSetupExtensions.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Actions/InputActionSetupExtensions.cs @@ -1,5 +1,4 @@ using System; -using System.Diagnostics; using UnityEngine.InputSystem.Layouts; using UnityEngine.InputSystem.Utilities; @@ -316,11 +315,12 @@ public static BindingSyntax AddBinding(this InputAction action, string path, str /// Be extremely careful in enabling/disabling tracking before internal calls since those may otherwise /// be incorrectly registered. /// - [Conditional("UNITY_EDITOR")] + #if UNITY_EDITOR private static void RegisterApiUsage(UnityEngine.InputSystem.Editor.InputActionCodeAuthoringAnalytic.Api api) { UnityEngine.InputSystem.Editor.InputActionCodeAuthoringAnalytic.Register(api); } + #endif /// /// Add a binding that references the given and triggers @@ -365,7 +365,9 @@ public static BindingSyntax AddBinding(this InputAction action, InputControl con /// public static BindingSyntax AddBinding(this InputAction action, InputBinding binding = default) { + #if UNITY_EDITOR RegisterApiUsage(UnityEngine.InputSystem.Editor.InputActionCodeAuthoringAnalytic.Api.AddBinding); + #endif if (action == null) throw new ArgumentNullException(nameof(action)); @@ -496,7 +498,9 @@ public static BindingSyntax AddBinding(this InputActionMap actionMap, string pat /// public static BindingSyntax AddBinding(this InputActionMap actionMap, InputBinding binding) { + #if UNITY_EDITOR RegisterApiUsage(UnityEngine.InputSystem.Editor.InputActionCodeAuthoringAnalytic.Api.AddBinding); + #endif if (actionMap == null) throw new ArgumentNullException(nameof(actionMap)); @@ -521,7 +525,9 @@ public static BindingSyntax AddBinding(this InputActionMap actionMap, InputBindi public static CompositeSyntax AddCompositeBinding(this InputAction action, string composite, string interactions = null, string processors = null) { + #if UNITY_EDITOR RegisterApiUsage(UnityEngine.InputSystem.Editor.InputActionCodeAuthoringAnalytic.Api.AddCompositeBinding); + #endif if (action == null) throw new ArgumentNullException(nameof(action)); @@ -602,7 +608,9 @@ private static int AddBindingInternal(InputActionMap map, InputBinding binding, /// of ). public static BindingSyntax ChangeBinding(this InputAction action, int index) { + #if UNITY_EDITOR RegisterApiUsage(UnityEngine.InputSystem.Editor.InputActionCodeAuthoringAnalytic.Api.ChangeBinding); + #endif if (action == null) throw new ArgumentNullException(nameof(action)); @@ -662,7 +670,9 @@ public static BindingSyntax ChangeBinding(this InputAction action, string name) /// of ). public static BindingSyntax ChangeBinding(this InputActionMap actionMap, int index) { + #if UNITY_EDITOR RegisterApiUsage(UnityEngine.InputSystem.Editor.InputActionCodeAuthoringAnalytic.Api.ChangeBinding); + #endif if (actionMap == null) throw new ArgumentNullException(nameof(actionMap)); @@ -862,7 +872,9 @@ public static BindingSyntax ChangeBinding(this InputAction action, InputBinding /// public static BindingSyntax ChangeCompositeBinding(this InputAction action, string compositeName) { + #if UNITY_EDITOR RegisterApiUsage(UnityEngine.InputSystem.Editor.InputActionCodeAuthoringAnalytic.Api.ChangeCompositeBinding); + #endif if (action == null) throw new ArgumentNullException(nameof(action)); @@ -905,7 +917,9 @@ public static BindingSyntax ChangeCompositeBinding(this InputAction action, stri /// public static void Rename(this InputAction action, string newName) { + #if UNITY_EDITOR RegisterApiUsage(UnityEngine.InputSystem.Editor.InputActionCodeAuthoringAnalytic.Api.Rename); + #endif if (action == null) throw new ArgumentNullException(nameof(action)); @@ -949,7 +963,9 @@ public static void Rename(this InputAction action, string newName) /// public static void AddControlScheme(this InputActionAsset asset, InputControlScheme controlScheme) { + #if UNITY_EDITOR RegisterApiUsage(UnityEngine.InputSystem.Editor.InputActionCodeAuthoringAnalytic.Api.AddControlScheme); + #endif if (asset == null) throw new ArgumentNullException(nameof(asset)); @@ -1019,7 +1035,9 @@ public static ControlSchemeSyntax AddControlScheme(this InputActionAsset asset, /// public static void RemoveControlScheme(this InputActionAsset asset, string name) { + #if UNITY_EDITOR RegisterApiUsage(UnityEngine.InputSystem.Editor.InputActionCodeAuthoringAnalytic.Api.RemoveControlScheme); + #endif if (asset == null) throw new ArgumentNullException(nameof(asset)); @@ -1041,14 +1059,19 @@ public static void RemoveControlScheme(this InputActionAsset asset, string name) /// public static InputControlScheme WithBindingGroup(this InputControlScheme scheme, string bindingGroup) { + #if UNITY_EDITOR RegisterApiUsage(UnityEngine.InputSystem.Editor.InputActionCodeAuthoringAnalytic.Api.ControlSchemeWithBindingGroup); + #endif return new ControlSchemeSyntax(scheme).WithBindingGroup(bindingGroup).Done(); } public static InputControlScheme WithDevice(this InputControlScheme scheme, string controlPath, bool required) { + #if UNITY_EDITOR RegisterApiUsage(UnityEngine.InputSystem.Editor.InputActionCodeAuthoringAnalytic.Api.ControlSchemeWithDevice); + #endif + if (required) return new ControlSchemeSyntax(scheme).WithRequiredDevice(controlPath).Done(); return new ControlSchemeSyntax(scheme).WithOptionalDevice(controlPath).Done(); @@ -1056,25 +1079,37 @@ public static InputControlScheme WithDevice(this InputControlScheme scheme, stri public static InputControlScheme WithRequiredDevice(this InputControlScheme scheme, string controlPath) { + #if UNITY_EDITOR RegisterApiUsage(UnityEngine.InputSystem.Editor.InputActionCodeAuthoringAnalytic.Api.ControlSchemeWithRequiredDevice); + #endif + return new ControlSchemeSyntax(scheme).WithRequiredDevice(controlPath).Done(); } public static InputControlScheme WithOptionalDevice(this InputControlScheme scheme, string controlPath) { + #if UNITY_EDITOR RegisterApiUsage(UnityEngine.InputSystem.Editor.InputActionCodeAuthoringAnalytic.Api.ControlSchemeWithOptionalDevice); + #endif + return new ControlSchemeSyntax(scheme).WithOptionalDevice(controlPath).Done(); } public static InputControlScheme OrWithRequiredDevice(this InputControlScheme scheme, string controlPath) { + #if UNITY_EDITOR RegisterApiUsage(UnityEngine.InputSystem.Editor.InputActionCodeAuthoringAnalytic.Api.ControlSchemeOrWithRequiredDevice); + #endif + return new ControlSchemeSyntax(scheme).OrWithRequiredDevice(controlPath).Done(); } public static InputControlScheme OrWithOptionalDevice(this InputControlScheme scheme, string controlPath) { + #if UNITY_EDITOR RegisterApiUsage(UnityEngine.InputSystem.Editor.InputActionCodeAuthoringAnalytic.Api.ControlSchemeOrWithOptionalDevice); + #endif + return new ControlSchemeSyntax(scheme).OrWithOptionalDevice(controlPath).Done(); } diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/InputActionCodeAuthoringAnalytic.cs b/Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/InputActionCodeAuthoringAnalytic.cs index bbc6369ad1..20b686d5d8 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/InputActionCodeAuthoringAnalytic.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/InputActionCodeAuthoringAnalytic.cs @@ -11,9 +11,9 @@ namespace UnityEngine.InputSystem.Editor #endif // UNITY_2023_2_OR_NEWER internal class InputActionCodeAuthoringAnalytic : UnityEngine.InputSystem.InputAnalytics.IInputAnalytic { - private const string kEventName = "input_action_code_authoring"; - private const int kMaxEventsPerHour = 100; // default: 1000 - private const int kMaxNumberOfElements = 100; // default: 1000 + public const string kEventName = "input_action_code_authoring"; + public const int kMaxEventsPerHour = 100; // default: 1000 + public const int kMaxNumberOfElements = 100; // default: 1000 /// /// Enumeration type for code authoring APIs mapping to . From 6387763a6aeb21783cb2cd435ae268133f7de2af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ha=CC=8Akan=20Sidenvall?= Date: Thu, 12 Sep 2024 11:29:19 +0200 Subject: [PATCH 05/10] Fixed formatting --- .../Tests/InputSystem/CoreTests_Analytics.cs | 2 +- .../Actions/InputActionSetupExtensions.cs | 33 ++++++++++--------- .../InputActionCodeAuthoringAnalytic.cs | 18 +++++----- 3 files changed, 27 insertions(+), 26 deletions(-) diff --git a/Assets/Tests/InputSystem/CoreTests_Analytics.cs b/Assets/Tests/InputSystem/CoreTests_Analytics.cs index e652de926b..96bbd6844a 100644 --- a/Assets/Tests/InputSystem/CoreTests_Analytics.cs +++ b/Assets/Tests/InputSystem/CoreTests_Analytics.cs @@ -667,7 +667,7 @@ public void Analytics_ShouldReportPlayerInputManagerData() [Category("Analytics")] public void Analytics_ShouldReportCodeAuthoringAnalytic() { - + CollectAnalytics(InputActionCodeAuthoringAnalytic.kEventName); } #if UNITY_INPUT_SYSTEM_ENABLE_UI diff --git a/Packages/com.unity.inputsystem/InputSystem/Actions/InputActionSetupExtensions.cs b/Packages/com.unity.inputsystem/InputSystem/Actions/InputActionSetupExtensions.cs index 0ff2c20964..7a1b548757 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Actions/InputActionSetupExtensions.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Actions/InputActionSetupExtensions.cs @@ -305,7 +305,7 @@ public static BindingSyntax AddBinding(this InputAction action, string path, str groups = groups }); } - + /// /// Conditionally compiled helper for logging API usage of code-authored actions. /// @@ -320,6 +320,7 @@ private static void RegisterApiUsage(UnityEngine.InputSystem.Editor.InputActionC { UnityEngine.InputSystem.Editor.InputActionCodeAuthoringAnalytic.Register(api); } + #endif /// @@ -368,7 +369,7 @@ public static BindingSyntax AddBinding(this InputAction action, InputBinding bin #if UNITY_EDITOR RegisterApiUsage(UnityEngine.InputSystem.Editor.InputActionCodeAuthoringAnalytic.Api.AddBinding); #endif - + if (action == null) throw new ArgumentNullException(nameof(action)); @@ -501,7 +502,7 @@ public static BindingSyntax AddBinding(this InputActionMap actionMap, InputBindi #if UNITY_EDITOR RegisterApiUsage(UnityEngine.InputSystem.Editor.InputActionCodeAuthoringAnalytic.Api.AddBinding); #endif - + if (actionMap == null) throw new ArgumentNullException(nameof(actionMap)); if (binding.path == null) @@ -528,7 +529,7 @@ public static CompositeSyntax AddCompositeBinding(this InputAction action, strin #if UNITY_EDITOR RegisterApiUsage(UnityEngine.InputSystem.Editor.InputActionCodeAuthoringAnalytic.Api.AddCompositeBinding); #endif - + if (action == null) throw new ArgumentNullException(nameof(action)); if (string.IsNullOrEmpty(composite)) @@ -611,7 +612,7 @@ public static BindingSyntax ChangeBinding(this InputAction action, int index) #if UNITY_EDITOR RegisterApiUsage(UnityEngine.InputSystem.Editor.InputActionCodeAuthoringAnalytic.Api.ChangeBinding); #endif - + if (action == null) throw new ArgumentNullException(nameof(action)); @@ -673,7 +674,7 @@ public static BindingSyntax ChangeBinding(this InputActionMap actionMap, int ind #if UNITY_EDITOR RegisterApiUsage(UnityEngine.InputSystem.Editor.InputActionCodeAuthoringAnalytic.Api.ChangeBinding); #endif - + if (actionMap == null) throw new ArgumentNullException(nameof(actionMap)); if (index < 0 || index >= actionMap.m_Bindings.LengthSafe()) @@ -875,7 +876,7 @@ public static BindingSyntax ChangeCompositeBinding(this InputAction action, stri #if UNITY_EDITOR RegisterApiUsage(UnityEngine.InputSystem.Editor.InputActionCodeAuthoringAnalytic.Api.ChangeCompositeBinding); #endif - + if (action == null) throw new ArgumentNullException(nameof(action)); if (string.IsNullOrEmpty(compositeName)) @@ -920,7 +921,7 @@ public static void Rename(this InputAction action, string newName) #if UNITY_EDITOR RegisterApiUsage(UnityEngine.InputSystem.Editor.InputActionCodeAuthoringAnalytic.Api.Rename); #endif - + if (action == null) throw new ArgumentNullException(nameof(action)); if (string.IsNullOrEmpty(newName)) @@ -966,7 +967,7 @@ public static void AddControlScheme(this InputActionAsset asset, InputControlSch #if UNITY_EDITOR RegisterApiUsage(UnityEngine.InputSystem.Editor.InputActionCodeAuthoringAnalytic.Api.AddControlScheme); #endif - + if (asset == null) throw new ArgumentNullException(nameof(asset)); if (string.IsNullOrEmpty(controlScheme.name)) @@ -1038,7 +1039,7 @@ public static void RemoveControlScheme(this InputActionAsset asset, string name) #if UNITY_EDITOR RegisterApiUsage(UnityEngine.InputSystem.Editor.InputActionCodeAuthoringAnalytic.Api.RemoveControlScheme); #endif - + if (asset == null) throw new ArgumentNullException(nameof(asset)); if (string.IsNullOrEmpty(name)) @@ -1062,7 +1063,7 @@ public static InputControlScheme WithBindingGroup(this InputControlScheme scheme #if UNITY_EDITOR RegisterApiUsage(UnityEngine.InputSystem.Editor.InputActionCodeAuthoringAnalytic.Api.ControlSchemeWithBindingGroup); #endif - + return new ControlSchemeSyntax(scheme).WithBindingGroup(bindingGroup).Done(); } @@ -1071,7 +1072,7 @@ public static InputControlScheme WithDevice(this InputControlScheme scheme, stri #if UNITY_EDITOR RegisterApiUsage(UnityEngine.InputSystem.Editor.InputActionCodeAuthoringAnalytic.Api.ControlSchemeWithDevice); #endif - + if (required) return new ControlSchemeSyntax(scheme).WithRequiredDevice(controlPath).Done(); return new ControlSchemeSyntax(scheme).WithOptionalDevice(controlPath).Done(); @@ -1082,7 +1083,7 @@ public static InputControlScheme WithRequiredDevice(this InputControlScheme sche #if UNITY_EDITOR RegisterApiUsage(UnityEngine.InputSystem.Editor.InputActionCodeAuthoringAnalytic.Api.ControlSchemeWithRequiredDevice); #endif - + return new ControlSchemeSyntax(scheme).WithRequiredDevice(controlPath).Done(); } @@ -1091,7 +1092,7 @@ public static InputControlScheme WithOptionalDevice(this InputControlScheme sche #if UNITY_EDITOR RegisterApiUsage(UnityEngine.InputSystem.Editor.InputActionCodeAuthoringAnalytic.Api.ControlSchemeWithOptionalDevice); #endif - + return new ControlSchemeSyntax(scheme).WithOptionalDevice(controlPath).Done(); } @@ -1100,7 +1101,7 @@ public static InputControlScheme OrWithRequiredDevice(this InputControlScheme sc #if UNITY_EDITOR RegisterApiUsage(UnityEngine.InputSystem.Editor.InputActionCodeAuthoringAnalytic.Api.ControlSchemeOrWithRequiredDevice); #endif - + return new ControlSchemeSyntax(scheme).OrWithRequiredDevice(controlPath).Done(); } @@ -1109,7 +1110,7 @@ public static InputControlScheme OrWithOptionalDevice(this InputControlScheme sc #if UNITY_EDITOR RegisterApiUsage(UnityEngine.InputSystem.Editor.InputActionCodeAuthoringAnalytic.Api.ControlSchemeOrWithOptionalDevice); #endif - + return new ControlSchemeSyntax(scheme).OrWithOptionalDevice(controlPath).Done(); } diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/InputActionCodeAuthoringAnalytic.cs b/Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/InputActionCodeAuthoringAnalytic.cs index 20b686d5d8..4fb3a0f49d 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/InputActionCodeAuthoringAnalytic.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/InputActionCodeAuthoringAnalytic.cs @@ -39,13 +39,13 @@ public enum Api } private static readonly int[] m_Counters = new int[Enum.GetNames(typeof(Api)).Length]; - + public static void Register(Api api) { // Note: Currently discards detailed information and only sets a boolean (aggregated) value. ++m_Counters[(int)api]; } - + // Cache delegate private static readonly Action PlayModeChanged = OnPlayModeStateChange; @@ -65,7 +65,7 @@ private static void OnPlayModeStateChange(PlayModeStateChange change) new InputActionCodeAuthoringAnalytic().Send(); } } - + [InitializeOnEnterPlayMode] private static void Hook() { @@ -78,7 +78,7 @@ private InputActionCodeAuthoringAnalytic() { info = new InputAnalytics.InputAnalyticInfo(kEventName, kMaxEventsPerHour, kMaxNumberOfElements); } - + /// /// Represents InputAction code authoring editor data. /// @@ -103,7 +103,7 @@ public Data(bool usesCodeAuthoring) /// public bool usesCodeAuthoring; } - + #if UNITY_2023_2_OR_NEWER public bool TryGatherData(out UnityEngine.Analytics.IAnalytic.IData data, out Exception error) #else @@ -122,7 +122,7 @@ public bool TryGatherData(out InputAnalytics.IInputAnalyticData data, out Except break; } } - + data = new Data(usedCodeAuthoringDuringPlayMode); error = null; return true; @@ -133,10 +133,10 @@ public bool TryGatherData(out InputAnalytics.IInputAnalyticData data, out Except error = e; return false; } - } - + } + public InputAnalytics.InputAnalyticInfo info { get; } } } -#endif // UNITY_EDITOR \ No newline at end of file +#endif // UNITY_EDITOR From d8264ff093c065ce2e15ed622162eb99e3b0ec98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ha=CC=8Akan=20Sidenvall?= Date: Thu, 12 Sep 2024 14:57:19 +0200 Subject: [PATCH 06/10] Added test case --- .../Tests/InputSystem/CoreTests_Analytics.cs | 42 +++++++++++++++++++ .../InputActionCodeAuthoringAnalytic.cs | 3 +- 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/Assets/Tests/InputSystem/CoreTests_Analytics.cs b/Assets/Tests/InputSystem/CoreTests_Analytics.cs index 96bbd6844a..367cb0334e 100644 --- a/Assets/Tests/InputSystem/CoreTests_Analytics.cs +++ b/Assets/Tests/InputSystem/CoreTests_Analytics.cs @@ -668,6 +668,48 @@ public void Analytics_ShouldReportPlayerInputManagerData() public void Analytics_ShouldReportCodeAuthoringAnalytic() { CollectAnalytics(InputActionCodeAuthoringAnalytic.kEventName); + + // NOTE: We do not want to trigger entering/exiting play-mode for this small data-sanity check + // so just stick to triggering it explicitly. A better test would have been an editor test + // going in and out of play-mode for real but not clear if this is really possible. + + // Pretend we are entering play-mode + InputActionCodeAuthoringAnalytic.OnPlayModeStateChange(PlayModeStateChange.ExitingEditMode); + InputActionCodeAuthoringAnalytic.OnPlayModeStateChange(PlayModeStateChange.EnteredPlayMode); + + // Assert no data received + Assert.That(sentAnalyticsEvents.Count, Is.EqualTo(0)); + + // Pretend we are exiting play-mode + InputActionCodeAuthoringAnalytic.OnPlayModeStateChange(PlayModeStateChange.ExitingPlayMode); + InputActionCodeAuthoringAnalytic.OnPlayModeStateChange(PlayModeStateChange.EnteredEditMode); + + // Assert: Data received + Assert.That(sentAnalyticsEvents.Count, Is.EqualTo(1)); + Assert.That(sentAnalyticsEvents[0].name, Is.EqualTo(InputActionCodeAuthoringAnalytic.kEventName)); + Assert.That(sentAnalyticsEvents[0].data, Is.TypeOf()); + + var data0 = (InputActionCodeAuthoringAnalytic.Data)sentAnalyticsEvents[0].data; + Assert.That(data0.usesCodeAuthoring, Is.False); + + // Pretend we are entering play-mode + InputActionCodeAuthoringAnalytic.OnPlayModeStateChange(PlayModeStateChange.ExitingEditMode); + InputActionCodeAuthoringAnalytic.OnPlayModeStateChange(PlayModeStateChange.EnteredPlayMode); + + var action = new InputAction("Dance"); + action.AddBinding("/Space"); + + // Pretend we are exiting play-mode + InputActionCodeAuthoringAnalytic.OnPlayModeStateChange(PlayModeStateChange.ExitingPlayMode); + InputActionCodeAuthoringAnalytic.OnPlayModeStateChange(PlayModeStateChange.EnteredEditMode); + + // Assert: Data received + Assert.That(sentAnalyticsEvents.Count, Is.EqualTo(2)); + Assert.That(sentAnalyticsEvents[1].name, Is.EqualTo(InputActionCodeAuthoringAnalytic.kEventName)); + Assert.That(sentAnalyticsEvents[1].data, Is.TypeOf()); + + var data1 = (InputActionCodeAuthoringAnalytic.Data)sentAnalyticsEvents[1].data; + Assert.That(data1.usesCodeAuthoring, Is.True); } #if UNITY_INPUT_SYSTEM_ENABLE_UI diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/InputActionCodeAuthoringAnalytic.cs b/Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/InputActionCodeAuthoringAnalytic.cs index 4fb3a0f49d..e0156fe73f 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/InputActionCodeAuthoringAnalytic.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/InputActionCodeAuthoringAnalytic.cs @@ -49,7 +49,8 @@ public static void Register(Api api) // Cache delegate private static readonly Action PlayModeChanged = OnPlayModeStateChange; - private static void OnPlayModeStateChange(PlayModeStateChange change) + // Note: Internal visibility to simplify unit testing + internal static void OnPlayModeStateChange(PlayModeStateChange change) { Debug.Log("Play mode state change: " + change); if (change == PlayModeStateChange.ExitingEditMode) From bfde21a635be3a742ea8818534482d5ab270ae76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ha=CC=8Akan=20Sidenvall?= Date: Thu, 12 Sep 2024 15:13:48 +0200 Subject: [PATCH 07/10] Added suppressions where required --- .../Tests/InputSystem/CoreTests_Analytics.cs | 18 +++++++------- .../InputActionCodeAuthoringAnalytic.cs | 24 +++++++++++++++++++ .../Plugins/OnScreen/OnScreenStick.cs | 12 ++++++++++ .../Plugins/XR/TrackedPoseDriver.cs | 21 +++++++++++----- 4 files changed, 60 insertions(+), 15 deletions(-) diff --git a/Assets/Tests/InputSystem/CoreTests_Analytics.cs b/Assets/Tests/InputSystem/CoreTests_Analytics.cs index 367cb0334e..0ce59d9d70 100644 --- a/Assets/Tests/InputSystem/CoreTests_Analytics.cs +++ b/Assets/Tests/InputSystem/CoreTests_Analytics.cs @@ -668,7 +668,7 @@ public void Analytics_ShouldReportPlayerInputManagerData() public void Analytics_ShouldReportCodeAuthoringAnalytic() { CollectAnalytics(InputActionCodeAuthoringAnalytic.kEventName); - + // NOTE: We do not want to trigger entering/exiting play-mode for this small data-sanity check // so just stick to triggering it explicitly. A better test would have been an editor test // going in and out of play-mode for real but not clear if this is really possible. @@ -676,14 +676,14 @@ public void Analytics_ShouldReportCodeAuthoringAnalytic() // Pretend we are entering play-mode InputActionCodeAuthoringAnalytic.OnPlayModeStateChange(PlayModeStateChange.ExitingEditMode); InputActionCodeAuthoringAnalytic.OnPlayModeStateChange(PlayModeStateChange.EnteredPlayMode); - + // Assert no data received Assert.That(sentAnalyticsEvents.Count, Is.EqualTo(0)); - + // Pretend we are exiting play-mode InputActionCodeAuthoringAnalytic.OnPlayModeStateChange(PlayModeStateChange.ExitingPlayMode); InputActionCodeAuthoringAnalytic.OnPlayModeStateChange(PlayModeStateChange.EnteredEditMode); - + // Assert: Data received Assert.That(sentAnalyticsEvents.Count, Is.EqualTo(1)); Assert.That(sentAnalyticsEvents[0].name, Is.EqualTo(InputActionCodeAuthoringAnalytic.kEventName)); @@ -691,23 +691,23 @@ public void Analytics_ShouldReportCodeAuthoringAnalytic() var data0 = (InputActionCodeAuthoringAnalytic.Data)sentAnalyticsEvents[0].data; Assert.That(data0.usesCodeAuthoring, Is.False); - + // Pretend we are entering play-mode InputActionCodeAuthoringAnalytic.OnPlayModeStateChange(PlayModeStateChange.ExitingEditMode); InputActionCodeAuthoringAnalytic.OnPlayModeStateChange(PlayModeStateChange.EnteredPlayMode); - + var action = new InputAction("Dance"); action.AddBinding("/Space"); - + // Pretend we are exiting play-mode InputActionCodeAuthoringAnalytic.OnPlayModeStateChange(PlayModeStateChange.ExitingPlayMode); InputActionCodeAuthoringAnalytic.OnPlayModeStateChange(PlayModeStateChange.EnteredEditMode); - + // Assert: Data received Assert.That(sentAnalyticsEvents.Count, Is.EqualTo(2)); Assert.That(sentAnalyticsEvents[1].name, Is.EqualTo(InputActionCodeAuthoringAnalytic.kEventName)); Assert.That(sentAnalyticsEvents[1].data, Is.TypeOf()); - + var data1 = (InputActionCodeAuthoringAnalytic.Data)sentAnalyticsEvents[1].data; Assert.That(data1.usesCodeAuthoring, Is.True); } diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/InputActionCodeAuthoringAnalytic.cs b/Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/InputActionCodeAuthoringAnalytic.cs index e0156fe73f..1e8f39d7e1 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/InputActionCodeAuthoringAnalytic.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/InputActionCodeAuthoringAnalytic.cs @@ -40,12 +40,30 @@ public enum Api private static readonly int[] m_Counters = new int[Enum.GetNames(typeof(Api)).Length]; + /// + /// Registers a call to the associated API. + /// + /// Enumeration identifying the API. public static void Register(Api api) { + if (suppress) + return; + // Note: Currently discards detailed information and only sets a boolean (aggregated) value. ++m_Counters[(int)api]; } + /// + /// Suppresses the registration of analytics. + /// + /// + /// May be used to temporarily suppress analytics to avoid false positives from internal usage. + /// + public static bool suppress + { + get; set; + } + // Cache delegate private static readonly Action PlayModeChanged = OnPlayModeStateChange; @@ -58,12 +76,18 @@ internal static void OnPlayModeStateChange(PlayModeStateChange change) // Reset all counters when exiting edit mode for (var i = 0; i < m_Counters.Length; ++i) m_Counters[i] = 0; + + // Make sure not suppressed + suppress = false; } if (change == PlayModeStateChange.ExitingPlayMode) { // Send analytics and unhook delegate when exiting play-mode EditorApplication.playModeStateChanged -= PlayModeChanged; new InputActionCodeAuthoringAnalytic().Send(); + + // No reason to not suppress + suppress = true; } } diff --git a/Packages/com.unity.inputsystem/InputSystem/Plugins/OnScreen/OnScreenStick.cs b/Packages/com.unity.inputsystem/InputSystem/Plugins/OnScreen/OnScreenStick.cs index 153f24a580..66f74c3f58 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Plugins/OnScreen/OnScreenStick.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Plugins/OnScreen/OnScreenStick.cs @@ -91,10 +91,16 @@ private void Start() if (m_PointerDownAction == null) m_PointerDownAction = new InputAction(); + #if UNITY_EDITOR + InputActionCodeAuthoringAnalytic.suppress = true; + #endif m_PointerDownAction.AddBinding("/leftButton"); m_PointerDownAction.AddBinding("/tip"); m_PointerDownAction.AddBinding("/touch*/press"); m_PointerDownAction.AddBinding("/trigger"); + #if UNITY_EDITOR + InputActionCodeAuthoringAnalytic.suppress = false; + #endif } if (m_PointerMoveAction == null || m_PointerMoveAction.bindings.Count == 0) @@ -102,9 +108,15 @@ private void Start() if (m_PointerMoveAction == null) m_PointerMoveAction = new InputAction(); + #if UNITY_EDITOR + InputActionCodeAuthoringAnalytic.suppress = true; + #endif m_PointerMoveAction.AddBinding("/position"); m_PointerMoveAction.AddBinding("/position"); m_PointerMoveAction.AddBinding("/touch*/position"); + #if UNITY_EDITOR + InputActionCodeAuthoringAnalytic.suppress = false; + #endif } m_PointerDownAction.started += OnPointerDown; diff --git a/Packages/com.unity.inputsystem/InputSystem/Plugins/XR/TrackedPoseDriver.cs b/Packages/com.unity.inputsystem/InputSystem/Plugins/XR/TrackedPoseDriver.cs index ab14e41722..e7118c3a78 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Plugins/XR/TrackedPoseDriver.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Plugins/XR/TrackedPoseDriver.cs @@ -265,8 +265,7 @@ void BindPosition() if (m_PositionInput.reference == null) { - action.Rename($"{gameObject.name} - TPD - Position"); - action.Enable(); + RenameAndEnable(action, $"{gameObject.name} - TPD - Position"); } } @@ -285,8 +284,7 @@ void BindRotation() if (m_RotationInput.reference == null) { - action.Rename($"{gameObject.name} - TPD - Rotation"); - action.Enable(); + RenameAndEnable(action, $"{gameObject.name} - TPD - Rotation"); } } @@ -305,11 +303,22 @@ void BindTrackingState() if (m_TrackingStateInput.reference == null) { - action.Rename($"{gameObject.name} - TPD - Tracking State"); - action.Enable(); + RenameAndEnable(action, $"{gameObject.name} - TPD - Tracking State"); } } + private void RenameAndEnable(InputAction action, string name) + { +#if UNITY_EDITOR + Editor.InputActionCodeAuthoringAnalytic.suppress = true; +#endif + action.Rename(name); +#if UNITY_EDITOR + Editor.InputActionCodeAuthoringAnalytic.suppress = false; +#endif + action.Enable(); + } + void UnbindPosition() { if (!m_PositionBound) From 0bab6667b219603f0774dab945878839283e699f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ha=CC=8Akan=20Sidenvall?= Date: Thu, 12 Sep 2024 15:39:48 +0200 Subject: [PATCH 08/10] Renamed field to use snake case --- Assets/Tests/InputSystem/CoreTests_Analytics.cs | 4 ++-- .../Editor/Analytics/InputActionCodeAuthoringAnalytic.cs | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/Assets/Tests/InputSystem/CoreTests_Analytics.cs b/Assets/Tests/InputSystem/CoreTests_Analytics.cs index 0ce59d9d70..54466dd9c1 100644 --- a/Assets/Tests/InputSystem/CoreTests_Analytics.cs +++ b/Assets/Tests/InputSystem/CoreTests_Analytics.cs @@ -690,7 +690,7 @@ public void Analytics_ShouldReportCodeAuthoringAnalytic() Assert.That(sentAnalyticsEvents[0].data, Is.TypeOf()); var data0 = (InputActionCodeAuthoringAnalytic.Data)sentAnalyticsEvents[0].data; - Assert.That(data0.usesCodeAuthoring, Is.False); + Assert.That(data0.uses_code_authoring, Is.False); // Pretend we are entering play-mode InputActionCodeAuthoringAnalytic.OnPlayModeStateChange(PlayModeStateChange.ExitingEditMode); @@ -709,7 +709,7 @@ public void Analytics_ShouldReportCodeAuthoringAnalytic() Assert.That(sentAnalyticsEvents[1].data, Is.TypeOf()); var data1 = (InputActionCodeAuthoringAnalytic.Data)sentAnalyticsEvents[1].data; - Assert.That(data1.usesCodeAuthoring, Is.True); + Assert.That(data1.uses_code_authoring, Is.True); } #if UNITY_INPUT_SYSTEM_ENABLE_UI diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/InputActionCodeAuthoringAnalytic.cs b/Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/InputActionCodeAuthoringAnalytic.cs index 1e8f39d7e1..5c35219af9 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/InputActionCodeAuthoringAnalytic.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/InputActionCodeAuthoringAnalytic.cs @@ -2,6 +2,7 @@ using System; using UnityEditor; +using UnityEngine.Serialization; namespace UnityEngine.InputSystem.Editor { @@ -119,14 +120,14 @@ public struct Data : UnityEngine.InputSystem.InputAnalytics.IInputAnalyticData /// Specifies whether code authoring has been used. public Data(bool usesCodeAuthoring) { - this.usesCodeAuthoring = usesCodeAuthoring; + uses_code_authoring = usesCodeAuthoring; } /// /// Specifies whether code-authoring (Input Action setup via extensions) was used at least once /// during play-mode. /// - public bool usesCodeAuthoring; + public bool uses_code_authoring; } #if UNITY_2023_2_OR_NEWER From 4c4e8dda6b4f179ee5097a08a8c03e9dc2326e99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ha=CC=8Akan=20Sidenvall?= Date: Fri, 27 Sep 2024 09:18:22 +0200 Subject: [PATCH 09/10] Renamed analytic class and event to reflect the event of exiting play mode to allow for extensions. --- .../Tests/InputSystem/CoreTests_Analytics.cs | 30 ++++++++-------- .../Actions/InputActionSetupExtensions.cs | 34 +++++++++---------- ...alytic.cs => InputExitPlayModeAnalytic.cs} | 13 ++++--- ...meta => InputExitPlayModeAnalytic.cs.meta} | 0 .../Plugins/OnScreen/OnScreenStick.cs | 8 ++--- .../Plugins/XR/TrackedPoseDriver.cs | 4 +-- 6 files changed, 44 insertions(+), 45 deletions(-) rename Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/{InputActionCodeAuthoringAnalytic.cs => InputExitPlayModeAnalytic.cs} (92%) rename Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/{InputActionCodeAuthoringAnalytic.cs.meta => InputExitPlayModeAnalytic.cs.meta} (100%) diff --git a/Assets/Tests/InputSystem/CoreTests_Analytics.cs b/Assets/Tests/InputSystem/CoreTests_Analytics.cs index 54466dd9c1..e9892b3064 100644 --- a/Assets/Tests/InputSystem/CoreTests_Analytics.cs +++ b/Assets/Tests/InputSystem/CoreTests_Analytics.cs @@ -667,48 +667,48 @@ public void Analytics_ShouldReportPlayerInputManagerData() [Category("Analytics")] public void Analytics_ShouldReportCodeAuthoringAnalytic() { - CollectAnalytics(InputActionCodeAuthoringAnalytic.kEventName); + CollectAnalytics(InputExitPlayModeAnalytic.kEventName); // NOTE: We do not want to trigger entering/exiting play-mode for this small data-sanity check // so just stick to triggering it explicitly. A better test would have been an editor test // going in and out of play-mode for real but not clear if this is really possible. // Pretend we are entering play-mode - InputActionCodeAuthoringAnalytic.OnPlayModeStateChange(PlayModeStateChange.ExitingEditMode); - InputActionCodeAuthoringAnalytic.OnPlayModeStateChange(PlayModeStateChange.EnteredPlayMode); + InputExitPlayModeAnalytic.OnPlayModeStateChange(PlayModeStateChange.ExitingEditMode); + InputExitPlayModeAnalytic.OnPlayModeStateChange(PlayModeStateChange.EnteredPlayMode); // Assert no data received Assert.That(sentAnalyticsEvents.Count, Is.EqualTo(0)); // Pretend we are exiting play-mode - InputActionCodeAuthoringAnalytic.OnPlayModeStateChange(PlayModeStateChange.ExitingPlayMode); - InputActionCodeAuthoringAnalytic.OnPlayModeStateChange(PlayModeStateChange.EnteredEditMode); + InputExitPlayModeAnalytic.OnPlayModeStateChange(PlayModeStateChange.ExitingPlayMode); + InputExitPlayModeAnalytic.OnPlayModeStateChange(PlayModeStateChange.EnteredEditMode); // Assert: Data received Assert.That(sentAnalyticsEvents.Count, Is.EqualTo(1)); - Assert.That(sentAnalyticsEvents[0].name, Is.EqualTo(InputActionCodeAuthoringAnalytic.kEventName)); - Assert.That(sentAnalyticsEvents[0].data, Is.TypeOf()); + Assert.That(sentAnalyticsEvents[0].name, Is.EqualTo(InputExitPlayModeAnalytic.kEventName)); + Assert.That(sentAnalyticsEvents[0].data, Is.TypeOf()); - var data0 = (InputActionCodeAuthoringAnalytic.Data)sentAnalyticsEvents[0].data; + var data0 = (InputExitPlayModeAnalytic.Data)sentAnalyticsEvents[0].data; Assert.That(data0.uses_code_authoring, Is.False); // Pretend we are entering play-mode - InputActionCodeAuthoringAnalytic.OnPlayModeStateChange(PlayModeStateChange.ExitingEditMode); - InputActionCodeAuthoringAnalytic.OnPlayModeStateChange(PlayModeStateChange.EnteredPlayMode); + InputExitPlayModeAnalytic.OnPlayModeStateChange(PlayModeStateChange.ExitingEditMode); + InputExitPlayModeAnalytic.OnPlayModeStateChange(PlayModeStateChange.EnteredPlayMode); var action = new InputAction("Dance"); action.AddBinding("/Space"); // Pretend we are exiting play-mode - InputActionCodeAuthoringAnalytic.OnPlayModeStateChange(PlayModeStateChange.ExitingPlayMode); - InputActionCodeAuthoringAnalytic.OnPlayModeStateChange(PlayModeStateChange.EnteredEditMode); + InputExitPlayModeAnalytic.OnPlayModeStateChange(PlayModeStateChange.ExitingPlayMode); + InputExitPlayModeAnalytic.OnPlayModeStateChange(PlayModeStateChange.EnteredEditMode); // Assert: Data received Assert.That(sentAnalyticsEvents.Count, Is.EqualTo(2)); - Assert.That(sentAnalyticsEvents[1].name, Is.EqualTo(InputActionCodeAuthoringAnalytic.kEventName)); - Assert.That(sentAnalyticsEvents[1].data, Is.TypeOf()); + Assert.That(sentAnalyticsEvents[1].name, Is.EqualTo(InputExitPlayModeAnalytic.kEventName)); + Assert.That(sentAnalyticsEvents[1].data, Is.TypeOf()); - var data1 = (InputActionCodeAuthoringAnalytic.Data)sentAnalyticsEvents[1].data; + var data1 = (InputExitPlayModeAnalytic.Data)sentAnalyticsEvents[1].data; Assert.That(data1.uses_code_authoring, Is.True); } diff --git a/Packages/com.unity.inputsystem/InputSystem/Actions/InputActionSetupExtensions.cs b/Packages/com.unity.inputsystem/InputSystem/Actions/InputActionSetupExtensions.cs index 7a1b548757..6a1aa3e7a5 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Actions/InputActionSetupExtensions.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Actions/InputActionSetupExtensions.cs @@ -316,9 +316,9 @@ public static BindingSyntax AddBinding(this InputAction action, string path, str /// be incorrectly registered. /// #if UNITY_EDITOR - private static void RegisterApiUsage(UnityEngine.InputSystem.Editor.InputActionCodeAuthoringAnalytic.Api api) + private static void RegisterApiUsage(UnityEngine.InputSystem.Editor.InputExitPlayModeAnalytic.Api api) { - UnityEngine.InputSystem.Editor.InputActionCodeAuthoringAnalytic.Register(api); + UnityEngine.InputSystem.Editor.InputExitPlayModeAnalytic.Register(api); } #endif @@ -367,7 +367,7 @@ public static BindingSyntax AddBinding(this InputAction action, InputControl con public static BindingSyntax AddBinding(this InputAction action, InputBinding binding = default) { #if UNITY_EDITOR - RegisterApiUsage(UnityEngine.InputSystem.Editor.InputActionCodeAuthoringAnalytic.Api.AddBinding); + RegisterApiUsage(UnityEngine.InputSystem.Editor.InputExitPlayModeAnalytic.Api.AddBinding); #endif if (action == null) @@ -500,7 +500,7 @@ public static BindingSyntax AddBinding(this InputActionMap actionMap, string pat public static BindingSyntax AddBinding(this InputActionMap actionMap, InputBinding binding) { #if UNITY_EDITOR - RegisterApiUsage(UnityEngine.InputSystem.Editor.InputActionCodeAuthoringAnalytic.Api.AddBinding); + RegisterApiUsage(UnityEngine.InputSystem.Editor.InputExitPlayModeAnalytic.Api.AddBinding); #endif if (actionMap == null) @@ -527,7 +527,7 @@ public static CompositeSyntax AddCompositeBinding(this InputAction action, strin string interactions = null, string processors = null) { #if UNITY_EDITOR - RegisterApiUsage(UnityEngine.InputSystem.Editor.InputActionCodeAuthoringAnalytic.Api.AddCompositeBinding); + RegisterApiUsage(UnityEngine.InputSystem.Editor.InputExitPlayModeAnalytic.Api.AddCompositeBinding); #endif if (action == null) @@ -610,7 +610,7 @@ private static int AddBindingInternal(InputActionMap map, InputBinding binding, public static BindingSyntax ChangeBinding(this InputAction action, int index) { #if UNITY_EDITOR - RegisterApiUsage(UnityEngine.InputSystem.Editor.InputActionCodeAuthoringAnalytic.Api.ChangeBinding); + RegisterApiUsage(UnityEngine.InputSystem.Editor.InputExitPlayModeAnalytic.Api.ChangeBinding); #endif if (action == null) @@ -672,7 +672,7 @@ public static BindingSyntax ChangeBinding(this InputAction action, string name) public static BindingSyntax ChangeBinding(this InputActionMap actionMap, int index) { #if UNITY_EDITOR - RegisterApiUsage(UnityEngine.InputSystem.Editor.InputActionCodeAuthoringAnalytic.Api.ChangeBinding); + RegisterApiUsage(UnityEngine.InputSystem.Editor.InputExitPlayModeAnalytic.Api.ChangeBinding); #endif if (actionMap == null) @@ -874,7 +874,7 @@ public static BindingSyntax ChangeBinding(this InputAction action, InputBinding public static BindingSyntax ChangeCompositeBinding(this InputAction action, string compositeName) { #if UNITY_EDITOR - RegisterApiUsage(UnityEngine.InputSystem.Editor.InputActionCodeAuthoringAnalytic.Api.ChangeCompositeBinding); + RegisterApiUsage(UnityEngine.InputSystem.Editor.InputExitPlayModeAnalytic.Api.ChangeCompositeBinding); #endif if (action == null) @@ -919,7 +919,7 @@ public static BindingSyntax ChangeCompositeBinding(this InputAction action, stri public static void Rename(this InputAction action, string newName) { #if UNITY_EDITOR - RegisterApiUsage(UnityEngine.InputSystem.Editor.InputActionCodeAuthoringAnalytic.Api.Rename); + RegisterApiUsage(UnityEngine.InputSystem.Editor.InputExitPlayModeAnalytic.Api.Rename); #endif if (action == null) @@ -965,7 +965,7 @@ public static void Rename(this InputAction action, string newName) public static void AddControlScheme(this InputActionAsset asset, InputControlScheme controlScheme) { #if UNITY_EDITOR - RegisterApiUsage(UnityEngine.InputSystem.Editor.InputActionCodeAuthoringAnalytic.Api.AddControlScheme); + RegisterApiUsage(UnityEngine.InputSystem.Editor.InputExitPlayModeAnalytic.Api.AddControlScheme); #endif if (asset == null) @@ -1037,7 +1037,7 @@ public static ControlSchemeSyntax AddControlScheme(this InputActionAsset asset, public static void RemoveControlScheme(this InputActionAsset asset, string name) { #if UNITY_EDITOR - RegisterApiUsage(UnityEngine.InputSystem.Editor.InputActionCodeAuthoringAnalytic.Api.RemoveControlScheme); + RegisterApiUsage(UnityEngine.InputSystem.Editor.InputExitPlayModeAnalytic.Api.RemoveControlScheme); #endif if (asset == null) @@ -1061,7 +1061,7 @@ public static void RemoveControlScheme(this InputActionAsset asset, string name) public static InputControlScheme WithBindingGroup(this InputControlScheme scheme, string bindingGroup) { #if UNITY_EDITOR - RegisterApiUsage(UnityEngine.InputSystem.Editor.InputActionCodeAuthoringAnalytic.Api.ControlSchemeWithBindingGroup); + RegisterApiUsage(UnityEngine.InputSystem.Editor.InputExitPlayModeAnalytic.Api.ControlSchemeWithBindingGroup); #endif return new ControlSchemeSyntax(scheme).WithBindingGroup(bindingGroup).Done(); @@ -1070,7 +1070,7 @@ public static InputControlScheme WithBindingGroup(this InputControlScheme scheme public static InputControlScheme WithDevice(this InputControlScheme scheme, string controlPath, bool required) { #if UNITY_EDITOR - RegisterApiUsage(UnityEngine.InputSystem.Editor.InputActionCodeAuthoringAnalytic.Api.ControlSchemeWithDevice); + RegisterApiUsage(UnityEngine.InputSystem.Editor.InputExitPlayModeAnalytic.Api.ControlSchemeWithDevice); #endif if (required) @@ -1081,7 +1081,7 @@ public static InputControlScheme WithDevice(this InputControlScheme scheme, stri public static InputControlScheme WithRequiredDevice(this InputControlScheme scheme, string controlPath) { #if UNITY_EDITOR - RegisterApiUsage(UnityEngine.InputSystem.Editor.InputActionCodeAuthoringAnalytic.Api.ControlSchemeWithRequiredDevice); + RegisterApiUsage(UnityEngine.InputSystem.Editor.InputExitPlayModeAnalytic.Api.ControlSchemeWithRequiredDevice); #endif return new ControlSchemeSyntax(scheme).WithRequiredDevice(controlPath).Done(); @@ -1090,7 +1090,7 @@ public static InputControlScheme WithRequiredDevice(this InputControlScheme sche public static InputControlScheme WithOptionalDevice(this InputControlScheme scheme, string controlPath) { #if UNITY_EDITOR - RegisterApiUsage(UnityEngine.InputSystem.Editor.InputActionCodeAuthoringAnalytic.Api.ControlSchemeWithOptionalDevice); + RegisterApiUsage(UnityEngine.InputSystem.Editor.InputExitPlayModeAnalytic.Api.ControlSchemeWithOptionalDevice); #endif return new ControlSchemeSyntax(scheme).WithOptionalDevice(controlPath).Done(); @@ -1099,7 +1099,7 @@ public static InputControlScheme WithOptionalDevice(this InputControlScheme sche public static InputControlScheme OrWithRequiredDevice(this InputControlScheme scheme, string controlPath) { #if UNITY_EDITOR - RegisterApiUsage(UnityEngine.InputSystem.Editor.InputActionCodeAuthoringAnalytic.Api.ControlSchemeOrWithRequiredDevice); + RegisterApiUsage(UnityEngine.InputSystem.Editor.InputExitPlayModeAnalytic.Api.ControlSchemeOrWithRequiredDevice); #endif return new ControlSchemeSyntax(scheme).OrWithRequiredDevice(controlPath).Done(); @@ -1108,7 +1108,7 @@ public static InputControlScheme OrWithRequiredDevice(this InputControlScheme sc public static InputControlScheme OrWithOptionalDevice(this InputControlScheme scheme, string controlPath) { #if UNITY_EDITOR - RegisterApiUsage(UnityEngine.InputSystem.Editor.InputActionCodeAuthoringAnalytic.Api.ControlSchemeOrWithOptionalDevice); + RegisterApiUsage(UnityEngine.InputSystem.Editor.InputExitPlayModeAnalytic.Api.ControlSchemeOrWithOptionalDevice); #endif return new ControlSchemeSyntax(scheme).OrWithOptionalDevice(controlPath).Done(); diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/InputActionCodeAuthoringAnalytic.cs b/Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/InputExitPlayModeAnalytic.cs similarity index 92% rename from Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/InputActionCodeAuthoringAnalytic.cs rename to Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/InputExitPlayModeAnalytic.cs index 5c35219af9..731aa9d922 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/InputActionCodeAuthoringAnalytic.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/InputExitPlayModeAnalytic.cs @@ -10,9 +10,9 @@ namespace UnityEngine.InputSystem.Editor [UnityEngine.Analytics.AnalyticInfo(eventName: kEventName, maxEventsPerHour: kMaxEventsPerHour, maxNumberOfElements: kMaxNumberOfElements, vendorKey: UnityEngine.InputSystem.InputAnalytics.kVendorKey)] #endif // UNITY_2023_2_OR_NEWER - internal class InputActionCodeAuthoringAnalytic : UnityEngine.InputSystem.InputAnalytics.IInputAnalytic + internal class InputExitPlayModeAnalytic : UnityEngine.InputSystem.InputAnalytics.IInputAnalytic { - public const string kEventName = "input_action_code_authoring"; + public const string kEventName = "input_exit_playmode"; public const int kMaxEventsPerHour = 100; // default: 1000 public const int kMaxNumberOfElements = 100; // default: 1000 @@ -71,7 +71,6 @@ public static bool suppress // Note: Internal visibility to simplify unit testing internal static void OnPlayModeStateChange(PlayModeStateChange change) { - Debug.Log("Play mode state change: " + change); if (change == PlayModeStateChange.ExitingEditMode) { // Reset all counters when exiting edit mode @@ -85,7 +84,7 @@ internal static void OnPlayModeStateChange(PlayModeStateChange change) { // Send analytics and unhook delegate when exiting play-mode EditorApplication.playModeStateChanged -= PlayModeChanged; - new InputActionCodeAuthoringAnalytic().Send(); + new InputExitPlayModeAnalytic().Send(); // No reason to not suppress suppress = true; @@ -100,13 +99,13 @@ private static void Hook() EditorApplication.playModeStateChanged += PlayModeChanged; } - private InputActionCodeAuthoringAnalytic() + private InputExitPlayModeAnalytic() { info = new InputAnalytics.InputAnalyticInfo(kEventName, kMaxEventsPerHour, kMaxNumberOfElements); } /// - /// Represents InputAction code authoring editor data. + /// Represents data collected when exiting play-mode.. /// /// /// Ideally this struct should be readonly but then Unity cannot serialize/deserialize it. @@ -117,7 +116,7 @@ public struct Data : UnityEngine.InputSystem.InputAnalytics.IInputAnalyticData /// /// Creates a new Data instance. /// - /// Specifies whether code authoring has been used. + /// Specifies whether code authoring has been used during play-mode. public Data(bool usesCodeAuthoring) { uses_code_authoring = usesCodeAuthoring; diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/InputActionCodeAuthoringAnalytic.cs.meta b/Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/InputExitPlayModeAnalytic.cs.meta similarity index 100% rename from Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/InputActionCodeAuthoringAnalytic.cs.meta rename to Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/InputExitPlayModeAnalytic.cs.meta diff --git a/Packages/com.unity.inputsystem/InputSystem/Plugins/OnScreen/OnScreenStick.cs b/Packages/com.unity.inputsystem/InputSystem/Plugins/OnScreen/OnScreenStick.cs index b682ba9686..629f94beb8 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Plugins/OnScreen/OnScreenStick.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Plugins/OnScreen/OnScreenStick.cs @@ -92,14 +92,14 @@ private void Start() m_PointerDownAction = new InputAction(); #if UNITY_EDITOR - InputActionCodeAuthoringAnalytic.suppress = true; + InputExitPlayModeAnalytic.suppress = true; #endif m_PointerDownAction.AddBinding("/leftButton"); m_PointerDownAction.AddBinding("/tip"); m_PointerDownAction.AddBinding("/touch*/press"); m_PointerDownAction.AddBinding("/trigger"); #if UNITY_EDITOR - InputActionCodeAuthoringAnalytic.suppress = false; + InputExitPlayModeAnalytic.suppress = false; #endif } @@ -109,13 +109,13 @@ private void Start() m_PointerMoveAction = new InputAction(); #if UNITY_EDITOR - InputActionCodeAuthoringAnalytic.suppress = true; + InputExitPlayModeAnalytic.suppress = true; #endif m_PointerMoveAction.AddBinding("/position"); m_PointerMoveAction.AddBinding("/position"); m_PointerMoveAction.AddBinding("/touch*/position"); #if UNITY_EDITOR - InputActionCodeAuthoringAnalytic.suppress = false; + InputExitPlayModeAnalytic.suppress = false; #endif } diff --git a/Packages/com.unity.inputsystem/InputSystem/Plugins/XR/TrackedPoseDriver.cs b/Packages/com.unity.inputsystem/InputSystem/Plugins/XR/TrackedPoseDriver.cs index e7118c3a78..59b92283b5 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Plugins/XR/TrackedPoseDriver.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Plugins/XR/TrackedPoseDriver.cs @@ -310,11 +310,11 @@ void BindTrackingState() private void RenameAndEnable(InputAction action, string name) { #if UNITY_EDITOR - Editor.InputActionCodeAuthoringAnalytic.suppress = true; + Editor.InputExitPlayModeAnalytic.suppress = true; #endif action.Rename(name); #if UNITY_EDITOR - Editor.InputActionCodeAuthoringAnalytic.suppress = false; + Editor.InputExitPlayModeAnalytic.suppress = false; #endif action.Enable(); } From ad6813917781e240e7c273b1ccfad4af7dce6ade Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ha=CC=8Akan=20Sidenvall?= Date: Fri, 27 Sep 2024 11:11:42 +0200 Subject: [PATCH 10/10] Simplified reset code --- .../Editor/Analytics/InputExitPlayModeAnalytic.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/InputExitPlayModeAnalytic.cs b/Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/InputExitPlayModeAnalytic.cs index 731aa9d922..a978775bca 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/InputExitPlayModeAnalytic.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/Analytics/InputExitPlayModeAnalytic.cs @@ -74,8 +74,7 @@ internal static void OnPlayModeStateChange(PlayModeStateChange change) if (change == PlayModeStateChange.ExitingEditMode) { // Reset all counters when exiting edit mode - for (var i = 0; i < m_Counters.Length; ++i) - m_Counters[i] = 0; + Array.Clear(m_Counters, 0, m_Counters.Length); // Make sure not suppressed suppress = false; @@ -123,8 +122,7 @@ public Data(bool usesCodeAuthoring) } /// - /// Specifies whether code-authoring (Input Action setup via extensions) was used at least once - /// during play-mode. + /// Specifies whether code-authoring (Input Action setup via extensions) was used at least once during play-mode. /// public bool uses_code_authoring; }