Util.cs 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. using System.Diagnostics;
  2. namespace SRDebugger.Internal
  3. {
  4. using System.Collections.Generic;
  5. using System.ComponentModel;
  6. using System.Reflection;
  7. using SRF.Helpers;
  8. using UnityEngine;
  9. using UnityEngine.EventSystems;
  10. public static class SRDebuggerUtil
  11. {
  12. public static bool IsMobilePlatform
  13. {
  14. get
  15. {
  16. if (Application.isMobilePlatform)
  17. {
  18. return true;
  19. }
  20. switch (Application.platform)
  21. {
  22. #if UNITY_5 || UNITY_5_3_OR_NEWER
  23. case RuntimePlatform.WSAPlayerARM:
  24. case RuntimePlatform.WSAPlayerX64:
  25. case RuntimePlatform.WSAPlayerX86:
  26. #else
  27. case RuntimePlatform.MetroPlayerARM:
  28. case RuntimePlatform.MetroPlayerX64:
  29. case RuntimePlatform.MetroPlayerX86:
  30. #endif
  31. return true;
  32. default:
  33. return false;
  34. }
  35. }
  36. }
  37. /// <summary>
  38. /// If no event system exists, create one
  39. /// </summary>
  40. /// <returns>True if the event system was created as a result of this call</returns>
  41. public static bool EnsureEventSystemExists()
  42. {
  43. if (!Settings.Instance.EnableEventSystemGeneration)
  44. {
  45. return false;
  46. }
  47. if (EventSystem.current != null)
  48. {
  49. return false;
  50. }
  51. var e = Object.FindObjectOfType<EventSystem>();
  52. // Check if EventSystem is in the scene but not registered yet
  53. if (e != null && e.gameObject.activeSelf && e.enabled)
  54. {
  55. return false;
  56. }
  57. Debug.LogWarning("[SRDebugger] No EventSystem found in scene - creating a default one. Disable this behaviour in Window -> SRDebugger -> Settings Window -> Advanced)");
  58. CreateDefaultEventSystem();
  59. return true;
  60. }
  61. public static void CreateDefaultEventSystem()
  62. {
  63. var go = new GameObject("EventSystem (Created by SRDebugger, disable in Window -> SRDebugger -> Settings Window -> Advanced)");
  64. go.AddComponent<EventSystem>();
  65. #if ENABLE_INPUT_SYSTEM && ENABLE_LEGACY_INPUT_MANAGER
  66. switch (Settings.Instance.UIInputMode)
  67. {
  68. case Settings.UIModes.NewInputSystem:
  69. AddInputSystem(go);
  70. Debug.LogWarning("[SRDebugger] Automatically generated EventSystem is using Unity Input System (can be changed to use Legacy Input in Window -> SRDebugger -> Settings Window -> Advanced)");
  71. break;
  72. case Settings.UIModes.LegacyInputSystem:
  73. AddLegacyInputSystem(go);
  74. Debug.LogWarning("[SRDebugger] Automatically generated EventSystem is using Legacy Input (can be changed to use Unity Input System in Window -> SRDebugger -> Settings Window -> Advanced)");
  75. break;
  76. }
  77. #elif ENABLE_INPUT_SYSTEM
  78. AddInputSystem(go);
  79. #elif ENABLE_LEGACY_INPUT_MANAGER || (!ENABLE_INPUT_SYSTEM && !UNITY_2019_3_OR_NEWER)
  80. AddLegacyInputSystem(go);
  81. #endif
  82. }
  83. #if ENABLE_INPUT_SYSTEM
  84. private static void AddInputSystem(GameObject go)
  85. {
  86. go.AddComponent<UnityEngine.InputSystem.UI.InputSystemUIInputModule>();
  87. // Disable/re-enable to force some initialization.
  88. // fix for input not being recognized until component is toggled off then on
  89. go.SetActive(false);
  90. go.SetActive(true);
  91. }
  92. #endif
  93. #if ENABLE_LEGACY_INPUT_MANAGER || (!ENABLE_INPUT_SYSTEM && !UNITY_2019_3_OR_NEWER)
  94. private static void AddLegacyInputSystem(GameObject go)
  95. {
  96. go.AddComponent<StandaloneInputModule>();
  97. }
  98. #endif
  99. /// <summary>
  100. /// Scan <paramref name="obj" /> for valid options and return a collection of them.
  101. /// </summary>
  102. /// <param name="obj"></param>
  103. /// <returns></returns>
  104. public static List<OptionDefinition> ScanForOptions(object obj)
  105. {
  106. var options = new List<OptionDefinition>();
  107. #if NETFX_CORE
  108. var members = obj.GetType().GetTypeInfo().DeclaredMembers;
  109. #else
  110. var members =
  111. obj.GetType().GetMembers(BindingFlags.Instance | BindingFlags.Public | BindingFlags.GetProperty |
  112. BindingFlags.SetProperty | BindingFlags.InvokeMethod);
  113. #endif
  114. var ignoreAssembly = typeof(MonoBehaviour).Assembly;
  115. foreach (var memberInfo in members)
  116. {
  117. // Skip any properties that are from built-in Unity types (e.g. Behaviour, MonoBehaviour)
  118. if (memberInfo.DeclaringType != null && memberInfo.DeclaringType.Assembly == ignoreAssembly)
  119. {
  120. continue;
  121. }
  122. var browsable = memberInfo.GetCustomAttribute<BrowsableAttribute>();
  123. if (browsable != null)
  124. {
  125. if (!browsable.Browsable)
  126. continue;
  127. }
  128. // Find user-specified category name from attribute
  129. var categoryAttribute = SRReflection.GetAttribute<CategoryAttribute>(memberInfo);
  130. var category = categoryAttribute == null ? "Default" : categoryAttribute.Category;
  131. // Find user-specified sorting priority from attribute
  132. var sortAttribute = SRReflection.GetAttribute<SortAttribute>(memberInfo);
  133. var sortPriority = sortAttribute == null ? 0 : sortAttribute.SortPriority;
  134. // Find user-specified display name from attribute
  135. var nameAttribute = SRReflection.GetAttribute<DisplayNameAttribute>(memberInfo);
  136. var name = nameAttribute == null ? memberInfo.Name : nameAttribute.DisplayName;
  137. if (memberInfo is PropertyInfo)
  138. {
  139. var propertyInfo = memberInfo as PropertyInfo;
  140. // Only allow properties with public read/write
  141. #if NETFX_CORE
  142. if(propertyInfo.GetMethod == null)
  143. continue;
  144. // Ignore static members
  145. if (propertyInfo.GetMethod.IsStatic)
  146. continue;
  147. #else
  148. if (propertyInfo.GetGetMethod() == null)
  149. {
  150. continue;
  151. }
  152. // Ignore static members
  153. if ((propertyInfo.GetGetMethod().Attributes & MethodAttributes.Static) != 0)
  154. {
  155. continue;
  156. }
  157. #endif
  158. options.Add(new OptionDefinition(name, category, sortPriority,
  159. new SRF.Helpers.PropertyReference(obj, propertyInfo)));
  160. }
  161. else if (memberInfo is MethodInfo)
  162. {
  163. var methodInfo = memberInfo as MethodInfo;
  164. if (methodInfo.IsStatic)
  165. {
  166. continue;
  167. }
  168. // Skip methods with parameters or non-void return type
  169. if (methodInfo.ReturnType != typeof (void) || methodInfo.GetParameters().Length > 0)
  170. {
  171. continue;
  172. }
  173. options.Add(new OptionDefinition(name, category, sortPriority,
  174. new SRF.Helpers.MethodReference(obj, methodInfo)));
  175. }
  176. }
  177. return options;
  178. }
  179. public static string GetNumberString(int value, int max, string exceedsMaxString)
  180. {
  181. if (value >= max)
  182. {
  183. return exceedsMaxString;
  184. }
  185. return value.ToString();
  186. }
  187. public static void ConfigureCanvas(Canvas canvas)
  188. {
  189. if (Settings.Instance.UseDebugCamera)
  190. {
  191. canvas.worldCamera = Service.DebugCamera.Camera;
  192. canvas.renderMode = RenderMode.ScreenSpaceCamera;
  193. }
  194. }
  195. }
  196. }