RectTransformDataDrawer.cs 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using UnityEditor;
  5. using UnityEngine;
  6. namespace TheraBytes.BetterUi.Editor
  7. {
  8. [CustomPropertyDrawer(typeof(RectTransformData)), CanEditMultipleObjects]
  9. public class RectTransformDataDrawer : PropertyDrawer
  10. {
  11. static int floatFieldHash = "FloatFieldHash".GetHashCode();
  12. private class Styles
  13. {
  14. public static readonly GUIStyle lockStyle = EditorStyles.miniButton;
  15. public static readonly GUIStyle measuringLabelStyle = new GUIStyle("PreOverlayLabel");
  16. public static readonly GUIContent anchorsContent = new GUIContent("Anchors");
  17. public static readonly GUIContent anchorMinContent = new GUIContent("Min", "The normalized position in the parent rectangle that the lower left corner is anchored to.");
  18. public static readonly GUIContent anchorMaxContent = new GUIContent("Max", "The normalized position in the parent rectangle that the upper right corner is anchored to.");
  19. public static readonly GUIContent positionContent = new GUIContent("Position", "The local position of the rectangle. The position specifies this rectangle's pivot relative to the anchor reference point.");
  20. public static readonly GUIContent sizeContent = new GUIContent("Size", "The size of the rectangle.");
  21. public static readonly GUIContent pivotContent = new GUIContent("Pivot", "The pivot point specified in normalized values between 0 and 1. The pivot point is the origin of this rectangle. Rotation and scaling is around this point.");
  22. public static readonly GUIContent transformScaleContent = new GUIContent("Scale", "The local scaling of this Game Object relative to the parent. This scales everything including image borders and text.");
  23. public static readonly GUIContent transformPositionZContent = new GUIContent("Pos Z", "Distance to offset the rectangle along the Z axis of the parent. The effect is visible if the Canvas uses a perspective camera, or if a parent RectTransform is rotated along the X or Y axis.");
  24. public static readonly GUIContent X = new GUIContent("X");
  25. public static readonly GUIContent Y = new GUIContent("Y");
  26. public static readonly GUIContent Z = new GUIContent("Z");
  27. }
  28. public static float HeightWithAnchorsExpanded { get { return 11.5f * EditorGUIUtility.singleLineHeight + 2; } }
  29. public static float HeightWithoutAnchorsExpanded { get { return 9.5f * EditorGUIUtility.singleLineHeight + 2; } }
  30. static Action<RectTransform, RectTransformData> pushCallback, pullCallback;
  31. public static void OverwritePushPullMethods(Action<RectTransform, RectTransformData> push, Action<RectTransform, RectTransformData> pull)
  32. {
  33. pushCallback = push;
  34. pullCallback = pull;
  35. }
  36. bool anchorExpand = true;
  37. public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
  38. {
  39. return (anchorExpand)
  40. ? HeightWithAnchorsExpanded
  41. : HeightWithoutAnchorsExpanded;
  42. }
  43. public override void OnGUI(Rect bounds, SerializedProperty prop, GUIContent label)
  44. {
  45. RectTransformData data = prop.GetValue<RectTransformData>();
  46. MonoBehaviour target = prop.serializedObject.targetObject as MonoBehaviour;
  47. GUI.Box(bounds, "");
  48. if (target != null && target.transform is RectTransform)
  49. {
  50. RectTransform rt = target.transform as RectTransform;
  51. // Pull
  52. if (GUI.Button(new Rect(bounds.position + new Vector2(5, 5), new Vector2(40, 40)), "Pull\n↓"))
  53. {
  54. Undo.RecordObject(target, "Pull From Rect Transform");
  55. if (pullCallback != null)
  56. {
  57. pullCallback(rt, data);
  58. }
  59. else
  60. {
  61. data.PullFromTransform(rt);
  62. }
  63. }
  64. // Push
  65. if (GUI.Button(new Rect(bounds.position + new Vector2(50, 25), new Vector2(40, 40)), "↑\nPush"))
  66. {
  67. Undo.RecordObject(target.transform, "Push To Rect Transform");
  68. if (pushCallback != null)
  69. {
  70. pushCallback(rt, data);
  71. }
  72. else
  73. {
  74. data.PushToTransform(rt);
  75. }
  76. }
  77. }
  78. // Fields
  79. DrawFields(prop, data, bounds, ref anchorExpand);
  80. }
  81. public static void DrawFields(SerializedProperty prop, RectTransformData data, Rect rect, ref bool anchorExpand)
  82. {
  83. SerializedProperty pivot = prop.FindPropertyRelative("Pivot");
  84. SerializedProperty rotation = prop.FindPropertyRelative("rotation");
  85. SerializedProperty euler = prop.FindPropertyRelative("EulerAngles");
  86. SerializedProperty saveAsEuler = prop.FindPropertyRelative("saveRotationAsEuler");
  87. SerializedProperty scale = prop.FindPropertyRelative("Scale");
  88. rect.width -= 0.5f * EditorGUIUtility.singleLineHeight;
  89. float yPos = 0;
  90. Space(ref yPos);
  91. SmartPositionAndSizeFields(prop, data, rect, ref yPos);
  92. SmartAnchorFields(prop, data, rect, ref yPos, ref anchorExpand);
  93. yPos += 2;
  94. SmartPivotField(pivot, data, rect, ref yPos);
  95. Space(ref yPos);
  96. RotationField(rotation, euler, saveAsEuler, data, rect, ref yPos);
  97. ScaleField(scale, data, rect, ref yPos);
  98. Space(ref yPos);
  99. prop.serializedObject.ApplyModifiedProperties();
  100. }
  101. static void Space(ref float yPos)
  102. {
  103. yPos += 0.5f * EditorGUIUtility.singleLineHeight;
  104. }
  105. private static Rect GetControlRect(float height, Rect rect, ref float yPos)
  106. {
  107. float y = yPos;
  108. yPos += height;
  109. return new Rect(rect.x, rect.y + y, rect.width, height);
  110. }
  111. private static void SmartPositionAndSizeFields(SerializedProperty prop, RectTransformData data, Rect rect, ref float yPos)
  112. {
  113. Rect controlRect = GetControlRect(EditorGUIUtility.singleLineHeight * 4f, rect, ref yPos);
  114. controlRect.height = EditorGUIUtility.singleLineHeight * 2f;
  115. bool equalAnchorX = data.AnchorMin.x == data.AnchorMax.x;
  116. bool equalAnchorY = data.AnchorMin.y == data.AnchorMax.y;
  117. // POS X
  118. Rect columnRect = GetColumnRect(controlRect, 0);
  119. if (equalAnchorX)
  120. {
  121. EditorGUI.BeginProperty(columnRect, null, prop.FindPropertyRelative("AnchoredPosition").FindPropertyRelative("x"));
  122. FloatFieldLabelAbove(prop, columnRect, () => data.AnchoredPosition.x, (float val) => data.AnchoredPosition = new Vector2(val, data.AnchoredPosition.y), DrivenTransformProperties.AnchoredPositionX, new GUIContent("Pos X"));
  123. EditorGUI.EndProperty();
  124. }
  125. else
  126. {
  127. EditorGUI.BeginProperty(columnRect, null, prop.FindPropertyRelative("AnchoredPosition").FindPropertyRelative("x"));
  128. EditorGUI.BeginProperty(columnRect, null, prop.FindPropertyRelative("SizeDelta").FindPropertyRelative("x"));
  129. FloatFieldLabelAbove(prop, columnRect, () => data.OffsetMin.x,
  130. (float val) => data.OffsetMin = new Vector2(val, data.OffsetMin.y),
  131. DrivenTransformProperties.None, new GUIContent("Left"));
  132. EditorGUI.EndProperty();
  133. EditorGUI.EndProperty();
  134. }
  135. // POS Y
  136. columnRect = GetColumnRect(controlRect, 1);
  137. if (equalAnchorY)
  138. {
  139. EditorGUI.BeginProperty(columnRect, null, prop.FindPropertyRelative("AnchoredPosition").FindPropertyRelative("y"));
  140. FloatFieldLabelAbove(prop, columnRect, () => data.AnchoredPosition.y, (float val) => data.AnchoredPosition = new Vector2(data.AnchoredPosition.x, val), DrivenTransformProperties.AnchoredPositionY, new GUIContent("Pos Y"));
  141. EditorGUI.EndProperty();
  142. }
  143. else
  144. {
  145. EditorGUI.BeginProperty(columnRect, null, prop.FindPropertyRelative("AnchoredPosition").FindPropertyRelative("y"));
  146. EditorGUI.BeginProperty(columnRect, null, prop.FindPropertyRelative("SizeDelta").FindPropertyRelative("y"));
  147. FloatFieldLabelAbove(prop, columnRect, () => -data.OffsetMax.y, (float val) => data.OffsetMax = new Vector2(data.OffsetMax.x, -val), DrivenTransformProperties.None, new GUIContent("Top"));
  148. EditorGUI.EndProperty();
  149. EditorGUI.EndProperty();
  150. }
  151. // POS Z
  152. columnRect = GetColumnRect(controlRect, 2);
  153. EditorGUI.BeginProperty(columnRect, null, prop.FindPropertyRelative("LocalPosition.z"));
  154. FloatFieldLabelAbove(prop, columnRect, () => data.LocalPosition.z, (float val) => data.LocalPosition = new Vector3(data.LocalPosition.x, data.LocalPosition.y, val), DrivenTransformProperties.AnchoredPositionZ, Styles.transformPositionZContent);
  155. EditorGUI.EndProperty();
  156. controlRect.y = controlRect.y + EditorGUIUtility.singleLineHeight * 2f;
  157. // Size Delta Width
  158. columnRect = GetColumnRect(controlRect, 0);
  159. if (equalAnchorX)
  160. {
  161. EditorGUI.BeginProperty(columnRect, null, prop.FindPropertyRelative("SizeDelta").FindPropertyRelative("x"));
  162. FloatFieldLabelAbove(prop, columnRect, () => data.SizeDelta.x, (float val) => data.SizeDelta = new Vector2(val, data.SizeDelta.y), DrivenTransformProperties.SizeDeltaX, (equalAnchorX ? new GUIContent("Width") : new GUIContent("W Delta")));
  163. EditorGUI.EndProperty();
  164. }
  165. else
  166. {
  167. EditorGUI.BeginProperty(columnRect, null, prop.FindPropertyRelative("AnchoredPosition").FindPropertyRelative("x"));
  168. EditorGUI.BeginProperty(columnRect, null, prop.FindPropertyRelative("SizeDelta").FindPropertyRelative("x"));
  169. FloatFieldLabelAbove(prop, columnRect, () => -data.OffsetMax.x, (float val) => data.OffsetMax = new Vector2(-val, data.OffsetMax.y), DrivenTransformProperties.None, new GUIContent("Right"));
  170. EditorGUI.EndProperty();
  171. EditorGUI.EndProperty();
  172. }
  173. // Size Delta Height
  174. columnRect = GetColumnRect(controlRect, 1);
  175. if (equalAnchorY)
  176. {
  177. EditorGUI.BeginProperty(columnRect, null, prop.FindPropertyRelative("SizeDelta").FindPropertyRelative("y"));
  178. FloatFieldLabelAbove(prop, columnRect, () => data.SizeDelta.y, (float val) => data.SizeDelta = new Vector2(data.SizeDelta.x, val), DrivenTransformProperties.SizeDeltaY, (equalAnchorY ? new GUIContent("Height") : new GUIContent("H Delta")));
  179. EditorGUI.EndProperty();
  180. }
  181. else
  182. {
  183. EditorGUI.BeginProperty(columnRect, null, prop.FindPropertyRelative("AnchoredPosition").FindPropertyRelative("y"));
  184. EditorGUI.BeginProperty(columnRect, null, prop.FindPropertyRelative("SizeDelta").FindPropertyRelative("y"));
  185. FloatFieldLabelAbove(prop, columnRect, () => data.OffsetMin.y, (float val) => data.OffsetMin = new Vector2(data.OffsetMin.x, val), DrivenTransformProperties.None, new GUIContent("Bottom"));
  186. EditorGUI.EndProperty();
  187. EditorGUI.EndProperty();
  188. }
  189. columnRect = controlRect;
  190. columnRect.height = EditorGUIUtility.singleLineHeight;
  191. columnRect.y = columnRect.y + EditorGUIUtility.singleLineHeight;
  192. columnRect.yMin = columnRect.yMin - 2f;
  193. columnRect.xMin = columnRect.xMax - 26f;
  194. columnRect.x = columnRect.x - columnRect.width;
  195. }
  196. private static void SmartAnchorFields(SerializedProperty prop, RectTransformData data, Rect rect, ref float yPos, ref bool anchorExpand)
  197. {
  198. Rect controlRect = GetControlRect(EditorGUIUtility.singleLineHeight * (float)((!anchorExpand ? 1 : 3)), rect, ref yPos);
  199. controlRect.x += 10;
  200. controlRect.width -= 10;
  201. controlRect.height = EditorGUIUtility.singleLineHeight;
  202. EditorGUI.BeginChangeCheck();
  203. anchorExpand = EditorGUI.Foldout(controlRect, anchorExpand, Styles.anchorsContent);
  204. if (EditorGUI.EndChangeCheck())
  205. {
  206. EditorPrefs.SetBool("RectTransformEditor.showAnchorProperties", anchorExpand);
  207. }
  208. if (!anchorExpand)
  209. return;
  210. EditorGUI.indentLevel = EditorGUI.indentLevel + 1;
  211. controlRect.y = controlRect.y + EditorGUIUtility.singleLineHeight;
  212. Vector2Field(controlRect,
  213. () => data.AnchorMin.x, (float val) => data.AnchorMin.x = val,
  214. () => data.AnchorMin.y, (float val) => data.AnchorMin.y = val,
  215. DrivenTransformProperties.AnchorMinX, DrivenTransformProperties.AnchorMinY,
  216. prop.FindPropertyRelative("AnchorMin").FindPropertyRelative("x"), prop.FindPropertyRelative("AnchorMin").FindPropertyRelative("y"),
  217. Styles.anchorMinContent);
  218. controlRect.y = controlRect.y + EditorGUIUtility.singleLineHeight;
  219. Vector2Field(controlRect,
  220. () => data.AnchorMax.x, (float val) => data.AnchorMax.x = val,
  221. () => data.AnchorMax.y, (float val) => data.AnchorMax.y = val,
  222. DrivenTransformProperties.AnchorMaxX, DrivenTransformProperties.AnchorMaxY,
  223. prop.FindPropertyRelative("AnchorMax").FindPropertyRelative("x"), prop.FindPropertyRelative("AnchorMax").FindPropertyRelative("y"),
  224. Styles.anchorMaxContent);
  225. EditorGUI.indentLevel = EditorGUI.indentLevel - 1;
  226. }
  227. private static void SmartPivotField(SerializedProperty pivotProp, RectTransformData data, Rect rect, ref float yPos)
  228. {
  229. Rect controlRect = GetControlRect(EditorGUIUtility.singleLineHeight, rect, ref yPos);
  230. controlRect.x += 10;
  231. controlRect.width -= 10;
  232. Vector2Field(controlRect,
  233. () => data.Pivot.x, (float val) => data.Pivot.x = val,
  234. () => data.Pivot.y, (float val) => data.Pivot.y = val,
  235. DrivenTransformProperties.PivotX, DrivenTransformProperties.PivotY,
  236. pivotProp.FindPropertyRelative("x"), pivotProp.FindPropertyRelative("y"),
  237. Styles.pivotContent);
  238. }
  239. private static Rect GetColumnRect(Rect totalRect, int column)
  240. {
  241. totalRect.xMin = totalRect.xMin - 20 + (EditorGUIUtility.labelWidth - 1f);
  242. Rect rect = totalRect;
  243. rect.xMin = rect.xMin + ((totalRect.width - 4f) * ((float)column / 3f) + (float)(column * 2));
  244. rect.width = (totalRect.width - 4f) / 3f;
  245. return rect;
  246. }
  247. private static void Vector2Field(Rect position, Func<float> xGetter, Action<float> xSetter, Func<float> yGetter, Action<float> ySetter,
  248. DrivenTransformProperties xDriven, DrivenTransformProperties yDriven, SerializedProperty xProperty, SerializedProperty yProperty, GUIContent label)
  249. {
  250. EditorGUI.PrefixLabel(position, -1, label);
  251. float lblW = EditorGUIUtility.labelWidth;
  252. int ident = EditorGUI.indentLevel;
  253. Rect columnRect = GetColumnRect(position, 0);
  254. Rect rect = GetColumnRect(position, 1);
  255. EditorGUIUtility.labelWidth = 13f;
  256. EditorGUI.indentLevel = 0;
  257. EditorGUI.BeginProperty(columnRect, Styles.X, xProperty);
  258. FloatField(xProperty, columnRect, xGetter, xSetter, xDriven, Styles.X);
  259. EditorGUI.EndProperty();
  260. EditorGUI.BeginProperty(columnRect, Styles.Y, yProperty);
  261. FloatField(yProperty, rect, yGetter, ySetter, yDriven, Styles.Y);
  262. EditorGUI.EndProperty();
  263. EditorGUIUtility.labelWidth = lblW;
  264. EditorGUI.indentLevel = ident;
  265. }
  266. private static void ScaleField(SerializedProperty prop, RectTransformData data, Rect rect, ref float yPos)
  267. {
  268. Rect controlRect = GetControlRect(EditorGUIUtility.singleLineHeight, rect, ref yPos);
  269. controlRect.x += 10;
  270. controlRect.width -= 10;
  271. EditorGUI.PrefixLabel(controlRect, -1, Styles.transformScaleContent);
  272. float lblW = EditorGUIUtility.labelWidth;
  273. int ident = EditorGUI.indentLevel;
  274. Rect rectX = GetColumnRect(controlRect, 0);
  275. Rect rectY = GetColumnRect(controlRect, 1);
  276. Rect rectZ = GetColumnRect(controlRect, 2);
  277. EditorGUIUtility.labelWidth = 13f;
  278. EditorGUI.indentLevel = 0;
  279. EditorGUI.BeginProperty(rectX, Styles.X, prop.FindPropertyRelative("x"));
  280. FloatField(prop, rectX, () => data.Scale.x, (val) => data.Scale.x = val, DrivenTransformProperties.ScaleX, Styles.X);
  281. EditorGUI.EndProperty();
  282. EditorGUI.BeginProperty(rectX, Styles.Y, prop.FindPropertyRelative("y"));
  283. FloatField(prop, rectY, () => data.Scale.y, (val) => data.Scale.y = val, DrivenTransformProperties.ScaleY, Styles.Y);
  284. EditorGUI.EndProperty();
  285. EditorGUI.BeginProperty(rectX, Styles.Z, prop.FindPropertyRelative("z"));
  286. FloatField(prop, rectZ, () => data.Scale.z, (val) => data.Scale.z = val, DrivenTransformProperties.ScaleZ, Styles.Z);
  287. EditorGUI.EndProperty();
  288. EditorGUIUtility.labelWidth = lblW;
  289. EditorGUI.indentLevel = ident;
  290. }
  291. private static void RotationField(SerializedProperty rotationProp, SerializedProperty eulerProp, SerializedProperty saveAsEulerProp, RectTransformData data, Rect rect, ref float yPos)
  292. {
  293. Rect controlRect = GetControlRect(EditorGUIUtility.singleLineHeight, rect, ref yPos);
  294. controlRect.x += 10;
  295. controlRect.width -= 10;
  296. Rect prefixRect = new Rect(controlRect.x, controlRect.y, EditorGUIUtility.labelWidth - 24, controlRect.height);//EditorGUI.PrefixLabel(controlRect, new GUIContent(""));
  297. string[] options = { "Rotation (Quaternion)", "Rotation (Euler)" };
  298. int prevIdx = (data.SaveRotationAsEuler) ? 1 : 0;
  299. int newIdx = EditorGUI.Popup(prefixRect, prevIdx, options);
  300. if(prevIdx != newIdx)
  301. {
  302. saveAsEulerProp.boolValue = (newIdx == 0) ? false : true;
  303. }
  304. float lblW = EditorGUIUtility.labelWidth;
  305. int ident = EditorGUI.indentLevel;
  306. Rect rectX = GetColumnRect(controlRect, 0);
  307. Rect rectY = GetColumnRect(controlRect, 1);
  308. Rect rectZ = GetColumnRect(controlRect, 2);
  309. EditorGUIUtility.labelWidth = 13f;
  310. EditorGUI.indentLevel = 0;
  311. if (data.SaveRotationAsEuler)
  312. {
  313. EditorGUI.BeginProperty(controlRect, GUIContent.none, eulerProp);
  314. Vector3 euler = data.EulerAngles;
  315. FloatField(eulerProp, rectX, () => data.EulerAngles.x, (val) => data.EulerAngles = new Vector3(val, euler.y, euler.z), DrivenTransformProperties.Rotation, Styles.X);
  316. FloatField(eulerProp, rectY, () => data.EulerAngles.y, (val) => data.EulerAngles = new Vector3(euler.x, val, euler.z), DrivenTransformProperties.Rotation, Styles.Y);
  317. FloatField(eulerProp, rectZ, () => data.EulerAngles.z, (val) => data.EulerAngles = new Vector3(euler.x, euler.y, val), DrivenTransformProperties.Rotation, Styles.Z);
  318. EditorGUI.EndProperty();
  319. rotationProp.quaternionValue = Quaternion.Euler(eulerProp.vector3Value);
  320. }
  321. else
  322. {
  323. EditorGUI.BeginProperty(controlRect, GUIContent.none, rotationProp);
  324. Vector3 euler = rotationProp.quaternionValue.eulerAngles;
  325. FloatField(rotationProp, rectX, () => data.Rotation.eulerAngles.x, (val) => data.Rotation = Quaternion.Euler(val, euler.y, euler.z), DrivenTransformProperties.Rotation, Styles.X);
  326. FloatField(rotationProp, rectY, () => data.Rotation.eulerAngles.y, (val) => data.Rotation = Quaternion.Euler(euler.x, val, euler.z), DrivenTransformProperties.Rotation, Styles.Y);
  327. FloatField(rotationProp, rectZ, () => data.Rotation.eulerAngles.z, (val) => data.Rotation = Quaternion.Euler(euler.x, euler.y, val), DrivenTransformProperties.Rotation, Styles.Z);
  328. EditorGUI.EndProperty();
  329. eulerProp.vector3Value = rotationProp.quaternionValue.eulerAngles;
  330. }
  331. EditorGUIUtility.labelWidth = lblW;
  332. EditorGUI.indentLevel = ident;
  333. }
  334. private static void FloatFieldLabelAbove(SerializedProperty prop, Rect position, Func<float> getter, Action<float> setter, DrivenTransformProperties driven, GUIContent label)
  335. {
  336. FloatField(prop, position, getter, setter, driven, label, true);
  337. }
  338. private static void FloatField(SerializedProperty prop, Rect position, Func<float> getter, Action<float> setter, DrivenTransformProperties driven, GUIContent label, bool labelAbove = false)
  339. {
  340. float val = getter();
  341. EditorGUI.BeginChangeCheck();
  342. float newVal;
  343. if (labelAbove)
  344. {
  345. int controlID = GUIUtility.GetControlID(floatFieldHash, FocusType.Keyboard, position);
  346. Rect labelRect = new Rect(position.x, position.y, position.width, EditorGUIUtility.singleLineHeight);
  347. Rect inputRect = new Rect(position.x, position.y + EditorGUIUtility.singleLineHeight, position.width, EditorGUIUtility.singleLineHeight);
  348. EditorGUI.HandlePrefixLabel(position, labelRect, label, controlID);
  349. newVal = EditorGUI.FloatField(inputRect, val);
  350. }
  351. else
  352. {
  353. newVal = EditorGUI.FloatField(position, label, val);
  354. }
  355. if (EditorGUI.EndChangeCheck())
  356. {
  357. Undo.RecordObject(prop.serializedObject.targetObject, "Inspector");
  358. setter(newVal);
  359. }
  360. }
  361. }
  362. }