ParticleScalerEditorWindow.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363
  1. 
  2. // =================================
  3. // Namespaces.
  4. // =================================
  5. using UnityEngine;
  6. using UnityEditor;
  7. using System.Linq;
  8. using System.Reflection;
  9. using System.Collections;
  10. using System.Collections.Generic;
  11. // =================================
  12. // Define namespace.
  13. // =================================
  14. namespace MirzaBeig
  15. {
  16. namespace EditorExtensions
  17. {
  18. namespace Utilities
  19. {
  20. // =================================
  21. // Classes.
  22. // =================================
  23. //[CustomEditor(typeof(ParticlePrefab))]
  24. //[CustomEditor(typeof(Transform))]
  25. //[CustomEditor(typeof(ParticleSystem))]
  26. //[CanEditMultipleObjects]
  27. public class ParticleScalerEditorWindow : EditorWindow
  28. {
  29. // =================================
  30. // Nested classes and structures.
  31. // =================================
  32. // ...
  33. // =================================
  34. // Variables.
  35. // =================================
  36. // Scale to apply.
  37. float customScale = 1.0f;
  38. // Also scale transform local position?
  39. bool scaleTransformLocalPosition = true;
  40. // Button sizes.
  41. float scalePresetButtonHeight = 25.0f;
  42. float modulePresetButtonHeight = 25.0f;
  43. float applyCustomScaleButtonHeight = 35.0f;
  44. // Playback.
  45. ParticlePlayback particlePlayback = new ParticlePlayback();
  46. // Selected objects in editor and all the particle systems components.
  47. List<GameObject> selectedGameObjectsWithParticleSystems = new List<GameObject>();
  48. // Particle systems and their scale values.
  49. // I also keep last frame's particle systems because I update
  50. // the list of particle systems on update. So clearing particles
  51. // inside the systems may not do anything as the particles are
  52. // updated and the list set to a length of zero before OnSelectionChange.
  53. List<ParticleSystem> particleSystems = new List<ParticleSystem>();
  54. List<ParticleSystem> particleSystemsFromLastFrame = new List<ParticleSystem>();
  55. // For labeling and tooltips.
  56. GUIContent guiContentLabel;
  57. // =================================
  58. // Functions.
  59. // =================================
  60. // ...
  61. [MenuItem("Window/Mirza Beig/Particle Scaler")]
  62. static void showEditor()
  63. {
  64. ParticleScalerEditorWindow window =
  65. EditorWindow.GetWindow<ParticleScalerEditorWindow>(false, "Mirza Beig - Particle Scaler");
  66. // Static init.
  67. // ...
  68. // Invoke non-static init.
  69. window.initialize();
  70. // Do a first check.
  71. window.OnSelectionChange();
  72. }
  73. // Initialize.
  74. void initialize()
  75. {
  76. }
  77. // ...
  78. void OnSelectionChange()
  79. {
  80. // Clear if set to clear on selection change.
  81. if (particlePlayback.clearParticlesOnSelectionChange)
  82. {
  83. ParticleEditorUtility.clearParticles(particleSystems);
  84. ParticleEditorUtility.clearParticles(particleSystemsFromLastFrame);
  85. particlePlayback.repaintEditorCameraWindows();
  86. }
  87. // Pause all selected particles.
  88. else if (!Application.isPlaying)
  89. {
  90. particlePlayback.pause(particleSystems);
  91. }
  92. // (Re-)verify current list of particles.
  93. ParticleEditorUtility.getSelectedParticleSystems(ref particleSystems, ref selectedGameObjectsWithParticleSystems);
  94. }
  95. // ...
  96. void applyScaleToAll(float scale)
  97. {
  98. Undo.RecordObjects(particleSystems.ToArray().Select(x => x.transform).ToArray(), "Scale Transform(s)");
  99. saveUndo();
  100. for (int i = 0; i < particleSystems.Count; i++)
  101. {
  102. particleSystems[i].scale(scale, scaleTransformLocalPosition);
  103. particlePlayback.loopback(particleSystems[i]);
  104. }
  105. }
  106. // ...
  107. void saveUndo()
  108. {
  109. Undo.RecordObjects(particleSystems.ToArray(), "Scale Particle System(s)");
  110. }
  111. // ...
  112. void setScalingModeForAll(ParticleSystemScalingMode mode)
  113. {
  114. saveUndo();
  115. for (int i = 0; i < particleSystems.Count; i++)
  116. {
  117. ParticleSystem.MainModule m = particleSystems[i].main;
  118. m.scalingMode = mode;
  119. }
  120. }
  121. // ...
  122. void OnGUI()
  123. {
  124. // Get windows.
  125. particlePlayback.updateEditorCameraWindowReferences();
  126. // Looks nicer.
  127. EditorGUILayout.Separator();
  128. // Scale settings.
  129. EditorGUILayout.LabelField("- Scale Settings:", EditorStyles.boldLabel);
  130. EditorGUILayout.Separator();
  131. // Extension options.
  132. guiContentLabel = new GUIContent("Scale Transform Position", "Scale local position in Transform component.");
  133. scaleTransformLocalPosition = EditorGUILayout.Toggle(guiContentLabel, scaleTransformLocalPosition);
  134. EditorGUILayout.Separator();
  135. guiContentLabel = new GUIContent("Custom Scale", "ParticleSystem component scale factor.");
  136. customScale = EditorGUILayout.Slider(guiContentLabel, customScale, 0.5f, 2.0f);
  137. EditorGUILayout.Separator();
  138. // Button to apply custom scale.
  139. guiContentLabel = new GUIContent("Apply Custom Scale",
  140. "Apply custom scaling factor to all ParticleSystem components in select GameObjects.");
  141. if (GUILayout.Button(guiContentLabel, GUILayout.Height(applyCustomScaleButtonHeight)))
  142. {
  143. applyScaleToAll(customScale);
  144. }
  145. //EditorGUILayout.Separator();
  146. GUI.enabled = particleSystems.Count != 0;
  147. // Buttons for quick-apply scale factor presets.
  148. EditorGUILayout.BeginHorizontal();
  149. {
  150. guiContentLabel = new GUIContent("Scale x0.5",
  151. "Apply a preset scale factor of x0.5.");
  152. if (GUILayout.Button(guiContentLabel, GUILayout.Height(scalePresetButtonHeight)))
  153. {
  154. applyScaleToAll(0.5f);
  155. }
  156. guiContentLabel = new GUIContent("Scale x0.75",
  157. "Apply a preset scale factor of x0.75.");
  158. if (GUILayout.Button(guiContentLabel, GUILayout.Height(scalePresetButtonHeight)))
  159. {
  160. applyScaleToAll(0.75f);
  161. }
  162. guiContentLabel = new GUIContent("Scale x1.5",
  163. "Apply a preset scale factor of x1.5.");
  164. if (GUILayout.Button(guiContentLabel, GUILayout.Height(scalePresetButtonHeight)))
  165. {
  166. applyScaleToAll(1.5f);
  167. }
  168. guiContentLabel = new GUIContent("Scale x2.0",
  169. "Apply a preset scale factor of x2.0.");
  170. if (GUILayout.Button(guiContentLabel, GUILayout.Height(scalePresetButtonHeight)))
  171. {
  172. applyScaleToAll(2.0f);
  173. }
  174. }
  175. EditorGUILayout.EndHorizontal();
  176. EditorGUILayout.Separator();
  177. GUI.enabled = true;
  178. EditorGUILayout.Separator();
  179. // Module settings.
  180. EditorGUILayout.LabelField("- Scale Mode Settings:", EditorStyles.boldLabel);
  181. EditorGUILayout.Separator();
  182. // Buttons for quick-apply scale factor presets.
  183. EditorGUILayout.BeginHorizontal();
  184. {
  185. guiContentLabel = new GUIContent("Hierarchy",
  186. "Change all particle systems to use \"Hierarchy\" as the scaling mode.");
  187. if (GUILayout.Button(guiContentLabel, GUILayout.Height(modulePresetButtonHeight)))
  188. {
  189. setScalingModeForAll(ParticleSystemScalingMode.Hierarchy);
  190. }
  191. guiContentLabel = new GUIContent("Local",
  192. "Change all particle systems to use \"Local\" as the scaling mode.");
  193. if (GUILayout.Button(guiContentLabel, GUILayout.Height(modulePresetButtonHeight)))
  194. {
  195. setScalingModeForAll(ParticleSystemScalingMode.Local);
  196. }
  197. guiContentLabel = new GUIContent("Shape",
  198. "Change all particle systems to use \"Shape\" as the scaling mode.");
  199. if (GUILayout.Button(guiContentLabel, GUILayout.Height(modulePresetButtonHeight)))
  200. {
  201. setScalingModeForAll(ParticleSystemScalingMode.Shape);
  202. }
  203. }
  204. EditorGUILayout.EndHorizontal();
  205. EditorGUILayout.Separator();
  206. // Playback settings.
  207. particlePlayback.GUIPlaybackSettings(particleSystems);
  208. EditorGUILayout.Separator();
  209. // Selected objects.
  210. particlePlayback.GUIParticleSelection(selectedGameObjectsWithParticleSystems);
  211. }
  212. // ...
  213. void OnInspectorUpdate()
  214. {
  215. Repaint();
  216. }
  217. // ...
  218. void Update()
  219. {
  220. // (Re-)verify current list of particles.
  221. particleSystemsFromLastFrame =
  222. new List<ParticleSystem>(particleSystems);
  223. ParticleEditorUtility.getSelectedParticleSystems(
  224. ref particleSystems, ref selectedGameObjectsWithParticleSystems);
  225. particlePlayback.update(particleSystems);
  226. }
  227. // ...
  228. void OnFocus()
  229. {
  230. // (Re-)verify current list of particles.
  231. ParticleEditorUtility.getSelectedParticleSystems(
  232. ref particleSystems, ref selectedGameObjectsWithParticleSystems);
  233. }
  234. // =================================
  235. // End functions.
  236. // =================================
  237. }
  238. // =================================
  239. // End namespace.
  240. // =================================
  241. }
  242. }
  243. }
  244. // =================================
  245. // --END-- //
  246. // =================================