MegaUndo.cs 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. // Created by Daniele Giardini - 2011 - Holoville - http://www.holoville.com
  2. using UnityEditor;
  3. using UnityEngine;
  4. #if UNITY_4_3 || UNITY_4_5 || UNITY_4_6 || UNITY_5_0 || UNITY_5_1 || UNITY_5_2 || UNITY_5_3 || UNITY_5_4 || UNITY_5_5 || UNITY_5_6 || UNITY_2017 || UNITY_2018 || UNITY_2019 || UNITY_2020
  5. public class MegaUndo
  6. {
  7. private Object defTarget;
  8. private string defName;
  9. //private bool autoSetDirty;
  10. //private bool listeningForGuiChanges;
  11. //private bool isMouseDown;
  12. //private Object waitingToRecordPrefab; // If different than NULL indicates the prefab instance that will need to record its state as soon as the mouse is released.
  13. public MegaUndo(Object p_target, string p_name) : this(p_target, p_name, true) { }
  14. public MegaUndo(Object p_target, string p_name, bool p_autoSetDirty)
  15. {
  16. defTarget = p_target;
  17. defName = p_name;
  18. //autoSetDirty = p_autoSetDirty;
  19. }
  20. public void CheckUndo() { CheckUndo(defTarget, defName); }
  21. public void CheckUndo(Object obj, string name)
  22. {
  23. }
  24. public bool CheckDirty(Object obj)
  25. {
  26. if ( GUI.changed ) // Wont work for dragging points
  27. {
  28. Undo.RecordObject(obj, defName);
  29. }
  30. return false; //CheckDirty(defTarget, defName);
  31. }
  32. public bool CheckDirty()
  33. {
  34. return CheckDirty(defTarget);
  35. }
  36. public static void SetSnapshotTarget(Object obj, string name)
  37. {
  38. Undo.RecordObject(obj, name);
  39. }
  40. public static void CreateSnapshot()
  41. {
  42. //Undo.CreateSnapshot();
  43. }
  44. public static void RegisterSnapshot()
  45. {
  46. //Undo.RegisterSnapshot();
  47. }
  48. public static void ClearSnapshotTarget()
  49. {
  50. //Undo.ClearSnapshotTarget();
  51. }
  52. }
  53. #else
  54. public class MegaUndo
  55. {
  56. private Object defTarget;
  57. private string defName;
  58. private bool autoSetDirty;
  59. private bool listeningForGuiChanges;
  60. private bool isMouseDown;
  61. private Object waitingToRecordPrefab; // If different than NULL indicates the prefab instance that will need to record its state as soon as the mouse is released.
  62. public MegaUndo(Object p_target, string p_name) : this(p_target, p_name, true) { }
  63. public MegaUndo(Object p_target, string p_name, bool p_autoSetDirty)
  64. {
  65. defTarget = p_target;
  66. defName = p_name;
  67. autoSetDirty = p_autoSetDirty;
  68. }
  69. public void CheckUndo() { CheckUndo(defTarget, defName); }
  70. public void CheckUndo(Object p_target) { CheckUndo(p_target, defName); }
  71. public void CheckUndo(Object p_target, string p_name)
  72. {
  73. Event e = Event.current;
  74. if ( waitingToRecordPrefab != null )
  75. {
  76. // Record eventual prefab instance modification.
  77. // TODO Avoid recording if nothing changed (no harm in doing so, but it would be nicer).
  78. switch ( e.type )
  79. {
  80. case EventType.MouseDown:
  81. case EventType.MouseUp:
  82. case EventType.KeyDown:
  83. case EventType.KeyUp:
  84. PrefabUtility.RecordPrefabInstancePropertyModifications(waitingToRecordPrefab);
  85. break;
  86. }
  87. }
  88. if ( (e.type == EventType.MouseDown && e.button == 0) || (e.type == EventType.KeyUp && e.keyCode == KeyCode.Tab) )
  89. {
  90. // When the LMB is pressed or the TAB key is released,
  91. // store a snapshot, but don't register it as an undo
  92. // (so that if nothing changes we avoid storing a useless undo).
  93. Undo.SetSnapshotTarget(p_target, p_name);
  94. Undo.CreateSnapshot();
  95. Undo.ClearSnapshotTarget(); // Not sure if this is necessary.
  96. listeningForGuiChanges = true;
  97. }
  98. }
  99. public bool CheckDirty() { return CheckDirty(defTarget, defName); }
  100. public bool CheckDirty(Object p_target) { return CheckDirty(p_target, defName); }
  101. public bool CheckDirty(Object p_target, string p_name)
  102. {
  103. if ( listeningForGuiChanges && GUI.changed )
  104. {
  105. // Some GUI value changed after pressing the mouse
  106. // or releasing the TAB key.
  107. // Register the previous snapshot as a valid undo.
  108. SetDirty(p_target, p_name);
  109. return true;
  110. }
  111. return false;
  112. }
  113. public void ForceDirty() { ForceDirty(defTarget, defName); }
  114. public void ForceDirty(Object p_target) { ForceDirty(p_target, defName); }
  115. public void ForceDirty(Object p_target, string p_name)
  116. {
  117. if ( !listeningForGuiChanges )
  118. {
  119. // Create a new snapshot.
  120. Undo.SetSnapshotTarget(p_target, p_name);
  121. Undo.CreateSnapshot();
  122. Undo.ClearSnapshotTarget();
  123. }
  124. SetDirty(p_target, p_name);
  125. }
  126. private void SetDirty(Object p_target, string p_name)
  127. {
  128. Undo.SetSnapshotTarget(p_target, p_name);
  129. Undo.RegisterSnapshot();
  130. Undo.ClearSnapshotTarget(); // Not sure if this is necessary.
  131. if ( autoSetDirty ) EditorUtility.SetDirty(p_target);
  132. listeningForGuiChanges = false;
  133. if ( CheckTargetIsPrefabInstance(p_target) )
  134. {
  135. // Prefab instance: record immediately and also wait for value to be changed and than re-record it
  136. // (otherwise prefab instances are not updated correctly when using Custom Inspectors).
  137. PrefabUtility.RecordPrefabInstancePropertyModifications(p_target);
  138. waitingToRecordPrefab = p_target;
  139. }
  140. else
  141. {
  142. waitingToRecordPrefab = null;
  143. }
  144. }
  145. private bool CheckTargetIsPrefabInstance(Object p_target)
  146. {
  147. return (PrefabUtility.GetPrefabType(p_target) == PrefabType.PrefabInstance);
  148. }
  149. public static void SetSnapshotTarget(Object obj, string name)
  150. {
  151. Undo.SetSnapshotTarget(obj, name);
  152. }
  153. public static void CreateSnapshot()
  154. {
  155. Undo.CreateSnapshot();
  156. }
  157. public static void RegisterSnapshot()
  158. {
  159. Undo.RegisterSnapshot();
  160. }
  161. public static void ClearSnapshotTarget()
  162. {
  163. Undo.ClearSnapshotTarget();
  164. }
  165. }
  166. #endif