No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

SerializedPropertyExtension.cs 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. using System;
  2. using System.Runtime.CompilerServices;
  3. using UnityEngine;
  4. namespace UnityEditor.Rendering
  5. {
  6. /// <summary>
  7. /// Extensions for <see cref="SerializedProperty"/>
  8. /// </summary>
  9. public static class SerializedPropertyExtension
  10. {
  11. /// <summary>
  12. /// Checks if the property target is alive
  13. /// </summary>
  14. /// <param name="property">The <see cref="SerializedProperty"/> to check </param>
  15. /// <returns>true, if the property is not null</returns>
  16. public static bool IsTargetAlive(this SerializedProperty property)
  17. => property != null && property.serializedObject.targetObject != null &&
  18. !property.serializedObject.targetObject.Equals(null);
  19. /// <summary>
  20. /// Helper to get an enum value from a SerializedProperty.
  21. /// This handle case where index do not correspond to enum value.
  22. /// </summary>
  23. /// <typeparam name="T">A valid <see cref="Enum"/></typeparam>
  24. /// <param name="property">The <see cref="SerializedProperty"/></param>
  25. /// <returns>The <see cref="Enum"/> value</returns>
  26. /// <example>
  27. /// <code>
  28. /// enum MyEnum
  29. /// {
  30. /// A = 2,
  31. /// B = 4,
  32. /// }
  33. /// public class MyObject : MonoBehavior
  34. /// {
  35. /// public MyEnum theEnum = MyEnum.A;
  36. /// }
  37. /// [CustomEditor(typeof(MyObject))]
  38. /// class MyObjectEditor : Editor
  39. /// {
  40. /// public override void OnInspectorGUI()
  41. /// {
  42. /// Debug.Log($"By enumValueIndex: {(MyEnum)serializedObject.FindProperty("theEnum").enumValueIndex}"); //write the value (MyEnum)(0)
  43. /// Debug.Log($"By GetEnumValue: {(MyEnum)serializedObject.FindProperty("theEnum").GetEnumValue&lt;MyEnum&gt;()}"); //write the value MyEnum.A
  44. /// }
  45. /// }
  46. /// </code>
  47. /// </example>
  48. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  49. public static T GetEnumValue<T>(this SerializedProperty property)
  50. where T : Enum
  51. => GetEnumValue_Internal<T>(property);
  52. /// <summary>
  53. /// Helper to get an enum name from a SerializedProperty
  54. /// </summary>
  55. /// <typeparam name="T">A valid <see cref="Enum"/></typeparam>
  56. /// <param name="property">The <see cref="SerializedProperty"/></param>
  57. /// <returns>The string containing the name of the enum</returns>
  58. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  59. public static string GetEnumName<T>(this SerializedProperty property)
  60. where T : Enum
  61. => property.hasMultipleDifferentValues
  62. ? "MultipleDifferentValues"
  63. : property.enumNames[property.enumValueIndex];
  64. /// <summary>
  65. /// Helper to set an enum value to a SerializedProperty
  66. /// </summary>
  67. /// <typeparam name="T">A valid <see cref="Enum"/></typeparam>
  68. /// <param name="property">The <see cref="SerializedProperty"/></param>
  69. /// <param name="value">The <see cref="Enum"/></param>
  70. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  71. public static void SetEnumValue<T>(this SerializedProperty property, T value)
  72. where T : Enum
  73. // intValue actually is the value underlying beside the enum
  74. => SetEnumValue_Internal(property, value);
  75. /// <summary>
  76. /// Get the value of a <see cref="SerializedProperty"/>.
  77. ///
  78. /// This function will be inlined by the compiler.
  79. /// Caution: The case of Enum is not handled here.
  80. /// </summary>
  81. /// <typeparam name="T">
  82. /// The type of the value to get.
  83. ///
  84. /// It is expected to be a supported type by the <see cref="SerializedProperty"/>.
  85. /// </typeparam>
  86. /// <param name="serializedProperty">The property to get.</param>
  87. /// <returns>The value of the property.</returns>
  88. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  89. public static T GetInline<T>(this SerializedProperty serializedProperty)
  90. where T : struct
  91. {
  92. if (typeof(T) == typeof(Color))
  93. return (T)(object)serializedProperty.colorValue;
  94. if (typeof(T) == typeof(string))
  95. return (T)(object)serializedProperty.stringValue;
  96. if (typeof(T) == typeof(double))
  97. return (T)(object)serializedProperty.doubleValue;
  98. if (typeof(T) == typeof(float))
  99. return (T)(object)serializedProperty.floatValue;
  100. if (typeof(T) == typeof(long))
  101. return (T)(object)serializedProperty.longValue;
  102. if (typeof(T) == typeof(int))
  103. return (T)(object)serializedProperty.intValue;
  104. if (typeof(T) == typeof(bool))
  105. return (T)(object)serializedProperty.boolValue;
  106. if (typeof(T) == typeof(BoundsInt))
  107. return (T)(object)serializedProperty.boundsIntValue;
  108. if (typeof(T) == typeof(Bounds))
  109. return (T)(object)serializedProperty.boundsValue;
  110. if (typeof(T) == typeof(RectInt))
  111. return (T)(object)serializedProperty.rectIntValue;
  112. if (typeof(T) == typeof(Rect))
  113. return (T)(object)serializedProperty.rectValue;
  114. if (typeof(T) == typeof(Quaternion))
  115. return (T)(object)serializedProperty.quaternionValue;
  116. if (typeof(T) == typeof(Vector2Int))
  117. return (T)(object)serializedProperty.vector2IntValue;
  118. if (typeof(T) == typeof(Vector4))
  119. return (T)(object)serializedProperty.vector4Value;
  120. if (typeof(T) == typeof(Vector3))
  121. return (T)(object)serializedProperty.vector3Value;
  122. if (typeof(T) == typeof(Vector2))
  123. return (T)(object)serializedProperty.vector2Value;
  124. if (typeof(T).IsEnum)
  125. return GetEnumValue_Internal<T>(serializedProperty);
  126. throw new ArgumentOutOfRangeException($"<{typeof(T)}> is not a valid type for a serialized property.");
  127. }
  128. /// <summary>
  129. /// Set the value of a <see cref="SerializedProperty"/>.
  130. ///
  131. /// This function will be inlined by the compiler.
  132. /// Caution: The case of Enum is not handled here.
  133. /// </summary>
  134. /// <typeparam name="T">
  135. /// The type of the value to set.
  136. ///
  137. /// It is expected to be a supported type by the <see cref="SerializedProperty"/>.
  138. /// </typeparam>
  139. /// <param name="serializedProperty">The property to set.</param>
  140. /// <param name="value">The value to set.</param>
  141. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  142. public static void SetInline<T>(this SerializedProperty serializedProperty, T value)
  143. where T : struct
  144. {
  145. if (typeof(T) == typeof(Color))
  146. {
  147. serializedProperty.colorValue = (Color)(object)value;
  148. return;
  149. }
  150. if (typeof(T) == typeof(string))
  151. {
  152. serializedProperty.stringValue = (string)(object)value;
  153. return;
  154. }
  155. if (typeof(T) == typeof(double))
  156. {
  157. serializedProperty.doubleValue = (double)(object)value;
  158. return;
  159. }
  160. if (typeof(T) == typeof(float))
  161. {
  162. serializedProperty.floatValue = (float)(object)value;
  163. return;
  164. }
  165. if (typeof(T) == typeof(long))
  166. {
  167. serializedProperty.longValue = (long)(object)value;
  168. return;
  169. }
  170. if (typeof(T) == typeof(int))
  171. {
  172. serializedProperty.intValue = (int)(object)value;
  173. return;
  174. }
  175. if (typeof(T) == typeof(bool))
  176. {
  177. serializedProperty.boolValue = (bool)(object)value;
  178. return;
  179. }
  180. if (typeof(T) == typeof(BoundsInt))
  181. {
  182. serializedProperty.boundsIntValue = (BoundsInt)(object)value;
  183. return;
  184. }
  185. if (typeof(T) == typeof(Bounds))
  186. {
  187. serializedProperty.boundsValue = (Bounds)(object)value;
  188. return;
  189. }
  190. if (typeof(T) == typeof(RectInt))
  191. {
  192. serializedProperty.rectIntValue = (RectInt)(object)value;
  193. return;
  194. }
  195. if (typeof(T) == typeof(Rect))
  196. {
  197. serializedProperty.rectValue = (Rect)(object)value;
  198. return;
  199. }
  200. if (typeof(T) == typeof(Quaternion))
  201. {
  202. serializedProperty.quaternionValue = (Quaternion)(object)value;
  203. return;
  204. }
  205. if (typeof(T) == typeof(Vector2Int))
  206. {
  207. serializedProperty.vector2IntValue = (Vector2Int)(object)value;
  208. return;
  209. }
  210. if (typeof(T) == typeof(Vector4))
  211. {
  212. serializedProperty.vector4Value = (Vector4)(object)value;
  213. return;
  214. }
  215. if (typeof(T) == typeof(Vector3))
  216. {
  217. serializedProperty.vector3Value = (Vector3)(object)value;
  218. return;
  219. }
  220. if (typeof(T) == typeof(Vector2))
  221. {
  222. serializedProperty.vector2Value = (Vector2)(object)value;
  223. return;
  224. }
  225. if (typeof(T).IsEnum)
  226. {
  227. SetEnumValue_Internal(serializedProperty, value);
  228. return;
  229. }
  230. throw new ArgumentOutOfRangeException($"<{typeof(T)}> is not a valid type for a serialized property.");
  231. }
  232. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  233. private static T GetEnumValue_Internal<T>(SerializedProperty property)
  234. // intValue actually is the value underlying beside the enum
  235. => (T)(object)property.intValue;
  236. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  237. private static void SetEnumValue_Internal<T>(SerializedProperty property, T value)
  238. // intValue actually is the value underlying beside the enum
  239. => property.intValue = (int)(object)value;
  240. }
  241. }