A game about forced loneliness, made by TACStudios
1#if UNITY_EDITOR
2using System;
3using UnityEditor;
4using UnityEditor.Build;
5using UnityEditor.Build.Content;
6using UnityEditor.Build.Reporting;
7using UnityEngine.Serialization;
8
9namespace UnityEngine.InputSystem.Editor
10{
11 /// <summary>
12 /// Analytics for tracking Player Input component user engagement in the editor.
13 /// </summary>
14#if UNITY_2023_2_OR_NEWER
15 [UnityEngine.Analytics.AnalyticInfo(eventName: kEventName, maxEventsPerHour: kMaxEventsPerHour,
16 maxNumberOfElements: kMaxNumberOfElements, vendorKey: UnityEngine.InputSystem.InputAnalytics.kVendorKey)]
17#endif // UNITY_2023_2_OR_NEWER
18 internal class InputBuildAnalytic : UnityEngine.InputSystem.InputAnalytics.IInputAnalytic
19 {
20 public const string kEventName = "input_build_completed";
21 public const int kMaxEventsPerHour = 100; // default: 1000
22 public const int kMaxNumberOfElements = 100; // default: 1000
23
24 private readonly BuildReport m_BuildReport;
25
26 public InputBuildAnalytic(BuildReport buildReport)
27 {
28 m_BuildReport = buildReport;
29 }
30
31 public InputAnalytics.InputAnalyticInfo info =>
32 new InputAnalytics.InputAnalyticInfo(kEventName, kMaxEventsPerHour, kMaxNumberOfElements);
33
34#if UNITY_2023_2_OR_NEWER
35 public bool TryGatherData(out UnityEngine.Analytics.IAnalytic.IData data, out Exception error)
36#else
37 public bool TryGatherData(out InputAnalytics.IInputAnalyticData data, out Exception error)
38#endif
39 {
40 InputSettings defaultSettings = null;
41 try
42 {
43 defaultSettings = ScriptableObject.CreateInstance<InputSettings>();
44 data = new InputBuildAnalyticData(m_BuildReport, InputSystem.settings, defaultSettings);
45 error = null;
46 return true;
47 }
48 catch (Exception e)
49 {
50 data = null;
51 error = e;
52 return false;
53 }
54 finally
55 {
56 if (defaultSettings != null)
57 Object.DestroyImmediate(defaultSettings);
58 }
59 }
60
61 /// <summary>
62 /// Input system build analytics data structure.
63 /// </summary>
64 [Serializable]
65 internal struct InputBuildAnalyticData : UnityEngine.InputSystem.InputAnalytics.IInputAnalyticData
66 {
67 #region InputSettings
68
69 [Serializable]
70 public enum UpdateMode
71 {
72 ProcessEventsInBothFixedAndDynamicUpdate = 0, // Note: Deprecated
73 ProcessEventsInDynamicUpdate = 1,
74 ProcessEventsInFixedUpdate = 2,
75 ProcessEventsManually = 3,
76 }
77
78 [Serializable]
79 public enum BackgroundBehavior
80 {
81 ResetAndDisableNonBackgroundDevices = 0,
82 ResetAndDisableAllDevices = 1,
83 IgnoreFocus = 2
84 }
85
86 [Serializable]
87 public enum EditorInputBehaviorInPlayMode
88 {
89 PointersAndKeyboardsRespectGameViewFocus = 0,
90 AllDevicesRespectGameViewFocus = 1,
91 AllDeviceInputAlwaysGoesToGameView = 2
92 }
93
94 [Serializable]
95 public enum InputActionPropertyDrawerMode
96 {
97 Compact = 0,
98 MultilineEffective = 1,
99 MultilineBoth = 2
100 }
101
102 public InputBuildAnalyticData(BuildReport report, InputSettings settings, InputSettings defaultSettings)
103 {
104 switch (settings.updateMode)
105 {
106 case 0: // ProcessEventsInBothFixedAndDynamicUpdate (deprecated/removed)
107 update_mode = UpdateMode.ProcessEventsInBothFixedAndDynamicUpdate;
108 break;
109 case InputSettings.UpdateMode.ProcessEventsManually:
110 update_mode = UpdateMode.ProcessEventsManually;
111 break;
112 case InputSettings.UpdateMode.ProcessEventsInDynamicUpdate:
113 update_mode = UpdateMode.ProcessEventsInDynamicUpdate;
114 break;
115 case InputSettings.UpdateMode.ProcessEventsInFixedUpdate:
116 update_mode = UpdateMode.ProcessEventsInFixedUpdate;
117 break;
118 default:
119 throw new Exception("Unsupported updateMode");
120 }
121
122 switch (settings.backgroundBehavior)
123 {
124 case InputSettings.BackgroundBehavior.IgnoreFocus:
125 background_behavior = BackgroundBehavior.IgnoreFocus;
126 break;
127 case InputSettings.BackgroundBehavior.ResetAndDisableAllDevices:
128 background_behavior = BackgroundBehavior.ResetAndDisableAllDevices;
129 break;
130 case InputSettings.BackgroundBehavior.ResetAndDisableNonBackgroundDevices:
131 background_behavior = BackgroundBehavior.ResetAndDisableNonBackgroundDevices;
132 break;
133 default:
134 throw new Exception("Unsupported background behavior");
135 }
136
137 switch (settings.editorInputBehaviorInPlayMode)
138 {
139 case InputSettings.EditorInputBehaviorInPlayMode.PointersAndKeyboardsRespectGameViewFocus:
140 editor_input_behavior_in_playmode = EditorInputBehaviorInPlayMode
141 .PointersAndKeyboardsRespectGameViewFocus;
142 break;
143 case InputSettings.EditorInputBehaviorInPlayMode.AllDevicesRespectGameViewFocus:
144 editor_input_behavior_in_playmode = EditorInputBehaviorInPlayMode
145 .AllDevicesRespectGameViewFocus;
146 break;
147 case InputSettings.EditorInputBehaviorInPlayMode.AllDeviceInputAlwaysGoesToGameView:
148 editor_input_behavior_in_playmode = EditorInputBehaviorInPlayMode
149 .AllDeviceInputAlwaysGoesToGameView;
150 break;
151 default:
152 throw new Exception("Unsupported editor background behavior");
153 }
154
155 switch (settings.inputActionPropertyDrawerMode)
156 {
157 case InputSettings.InputActionPropertyDrawerMode.Compact:
158 input_action_property_drawer_mode = InputActionPropertyDrawerMode.Compact;
159 break;
160 case InputSettings.InputActionPropertyDrawerMode.MultilineBoth:
161 input_action_property_drawer_mode = InputActionPropertyDrawerMode.MultilineBoth;
162 break;
163 case InputSettings.InputActionPropertyDrawerMode.MultilineEffective:
164 input_action_property_drawer_mode = InputActionPropertyDrawerMode.MultilineEffective;
165 break;
166 default:
167 throw new Exception("Unsupported editor property drawer mode");
168 }
169
170#if UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS
171 var inputSystemActions = InputSystem.actions;
172 var actionsPath = inputSystemActions == null ? null : AssetDatabase.GetAssetPath(inputSystemActions);
173 has_projectwide_input_action_asset = !string.IsNullOrEmpty(actionsPath);
174#else
175 has_projectwide_input_action_asset = false;
176#endif
177
178 var settingsPath = settings == null ? null : AssetDatabase.GetAssetPath(settings);
179 has_settings_asset = !string.IsNullOrEmpty(settingsPath);
180
181 compensate_for_screen_orientation = settings.compensateForScreenOrientation;
182 default_deadzone_min = settings.defaultDeadzoneMin;
183 default_deadzone_max = settings.defaultDeadzoneMax;
184 default_button_press_point = settings.defaultButtonPressPoint;
185 button_release_threshold = settings.buttonReleaseThreshold;
186 default_tap_time = settings.defaultTapTime;
187 default_slow_tap_time = settings.defaultSlowTapTime;
188 default_hold_time = settings.defaultHoldTime;
189 tap_radius = settings.tapRadius;
190 multi_tap_delay_time = settings.multiTapDelayTime;
191 max_event_bytes_per_update = settings.maxEventBytesPerUpdate;
192 max_queued_events_per_update = settings.maxQueuedEventsPerUpdate;
193 supported_devices = settings.supportedDevices.ToArray();
194 disable_redundant_events_merging = settings.disableRedundantEventsMerging;
195 shortcut_keys_consume_input = settings.shortcutKeysConsumeInput;
196
197 feature_optimized_controls_enabled = settings.IsFeatureEnabled(InputFeatureNames.kUseOptimizedControls);
198 feature_read_value_caching_enabled = settings.IsFeatureEnabled(InputFeatureNames.kUseReadValueCaching);
199 feature_paranoid_read_value_caching_checks_enabled =
200 settings.IsFeatureEnabled(InputFeatureNames.kParanoidReadValueCachingChecks);
201
202#if UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS
203 feature_use_imgui_editor_for_assets =
204 settings.IsFeatureEnabled(InputFeatureNames.kUseIMGUIEditorForAssets);
205#else
206 feature_use_imgui_editor_for_assets = false;
207#endif
208 feature_disable_unity_remote_support =
209 settings.IsFeatureEnabled(InputFeatureNames.kDisableUnityRemoteSupport);
210 feature_run_player_updates_in_editmode =
211 settings.IsFeatureEnabled(InputFeatureNames.kRunPlayerUpdatesInEditMode);
212
213 has_default_settings = InputSettings.AreEqual(settings, defaultSettings);
214
215 build_guid = report != null ? report.summary.guid.ToString() : string.Empty; // Allows testing
216 }
217
218 /// <summary>
219 /// Represents <see cref="InputSettings.updateMode"/> and indicates how the project handles updates.
220 /// </summary>
221 public UpdateMode update_mode;
222
223 /// <summary>
224 /// Represents <see cref="InputSettings.compensateForScreenOrientation"/> and if true automatically
225 /// adjust rotations when the screen orientation changes.
226 /// </summary>
227 public bool compensate_for_screen_orientation;
228
229 /// <summary>
230 /// Represents <see cref="InputSettings.backgroundBehavior"/> which determines what happens when application
231 /// focus changes and how the system handle input while running in the background.
232 /// </summary>
233 public BackgroundBehavior background_behavior;
234
235 // Note: InputSettings.filterNoiseOnCurrent not present since already deprecated when these analytics
236 // where added.
237
238 /// <summary>
239 /// Represents <see cref="InputSettings.defaultDeadzoneMin"/>
240 /// </summary>
241 public float default_deadzone_min;
242
243 /// <summary>
244 /// Represents <see cref="InputSettings.defaultDeadzoneMax"/>
245 /// </summary>
246 public float default_deadzone_max;
247
248 /// <summary>
249 /// Represents <see cref="InputSettings.defaultButtonPressPoint"/>
250 /// </summary>
251 public float default_button_press_point;
252
253 /// <summary>
254 /// Represents <see cref="InputSettings.buttonReleaseThreshold"/>
255 /// </summary>
256 public float button_release_threshold;
257
258 /// <summary>
259 /// Represents <see cref="InputSettings.defaultSlowTapTime"/>
260 /// </summary>
261 public float default_tap_time;
262
263 /// <summary>
264 /// Represents <see cref="InputSettings.defaultSlowTapTime"/>
265 /// </summary>
266 public float default_slow_tap_time;
267
268 /// <summary>
269 /// Represents <see cref="InputSettings.defaultHoldTime"/>
270 /// </summary>
271 public float default_hold_time;
272
273 /// <summary>
274 /// Represents <see cref="InputSettings.tapRadius"/>
275 /// </summary>
276 public float tap_radius;
277
278 /// <summary>
279 /// Represents <see cref="InputSettings.multiTapDelayTime"/>
280 /// </summary>
281 public float multi_tap_delay_time;
282
283 /// <summary>
284 /// Represents <see cref="InputSettings.editorInputBehaviorInPlayMode"/>
285 /// </summary>
286 public EditorInputBehaviorInPlayMode editor_input_behavior_in_playmode;
287
288 /// <summary>
289 /// Represents <see cref="InputSettings.inputActionPropertyDrawerMode"/>
290 /// </summary>
291 public InputActionPropertyDrawerMode input_action_property_drawer_mode;
292
293 /// <summary>
294 /// Represents <see cref="InputSettings.maxEventBytesPerUpdate"/>
295 /// </summary>
296 public int max_event_bytes_per_update;
297
298 /// <summary>
299 /// Represents <see cref="InputSettings.maxQueuedEventsPerUpdate"/>
300 /// </summary>
301 public int max_queued_events_per_update;
302
303 /// <summary>
304 /// Represents <see cref="InputSettings.supportedDevices"/>
305 /// </summary>
306 public string[] supported_devices;
307
308 /// <summary>
309 /// Represents <see cref="InputSettings.disableRedundantEventsMerging"/>
310 /// </summary>
311 public bool disable_redundant_events_merging;
312
313 /// <summary>
314 /// Represents <see cref="InputSettings.shortcutKeysConsumeInput"/>
315 /// </summary>
316 public bool shortcut_keys_consume_input;
317
318 #endregion
319
320 #region Feature flag settings
321
322 /// <summary>
323 /// Represents internal feature flag <see cref="InputFeatureNames.kUseOptimizedControls"/> as defined
324 /// in Input System 1.8.x.
325 /// </summary>
326 public bool feature_optimized_controls_enabled;
327
328 /// <summary>
329 /// Represents internal feature flag <see cref="InputFeatureNames.kUseReadValueCaching" /> as defined
330 /// in Input System 1.8.x.
331 /// </summary>
332 public bool feature_read_value_caching_enabled;
333
334 /// <summary>
335 /// Represents internal feature flag <see cref="InputFeatureNames.kParanoidReadValueCachingChecks" />
336 /// as defined in InputSystem 1.8.x.
337 /// </summary>
338 public bool feature_paranoid_read_value_caching_checks_enabled;
339
340 /// <summary>
341 /// Represents internal feature flag <see cref="InputFeatureNames.kUseIMGUIEditorForAssets" />
342 /// as defined in InputSystem 1.8.x.
343 /// </summary>
344 public bool feature_use_imgui_editor_for_assets;
345
346 /// <summary>
347 /// Represents internal feature flag <see cref="InputFeatureNames.kDisableUnityRemoteSupport" />
348 /// as defined in InputSystem 1.8.x.
349 /// </summary>
350 public bool feature_disable_unity_remote_support;
351
352 /// <summary>
353 /// Represents internal feature flag <see cref="InputFeatureNames.kRunPlayerUpdatesInEditMode" />
354 /// as defined in InputSystem 1.8.x.
355 /// </summary>
356 public bool feature_run_player_updates_in_editmode;
357
358 #endregion
359
360 #region
361
362 /// <summary>
363 /// Specifies whether the project is using a project-wide input actions asset or not.
364 /// </summary>
365 public bool has_projectwide_input_action_asset;
366
367 /// <summary>
368 /// Specifies whether the project is using a user-provided settings asset or not.
369 /// </summary>
370 public bool has_settings_asset;
371
372 /// <summary>
373 /// Specifies whether the settings asset (if present) of the built project is equal to default settings
374 /// or not. In case of no settings asset this is also true since implicitly using default settings.
375 /// </summary>
376 public bool has_default_settings;
377
378 /// <summary>
379 /// A unique GUID identifying the build.
380 /// </summary>
381 public string build_guid;
382
383 #endregion
384 }
385
386 /// <summary>
387 /// Input System build analytics.
388 /// </summary>
389 internal class ReportProcessor : IPostprocessBuildWithReport
390 {
391 public int callbackOrder => int.MaxValue;
392
393 public void OnPostprocessBuild(BuildReport report)
394 {
395 InputSystem.s_Manager?.m_Runtime?.SendAnalytic(new InputBuildAnalytic(report));
396 }
397 }
398 }
399}
400#endif