ParticleSystemHierarchyEditor.cs 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. using UnityEngine;
  2. using UnityEditor;
  3. using UnityEditor.SceneManagement;
  4. [InitializeOnLoad]
  5. public class ParticleSystemHierarchyEditor
  6. {
  7. static ParticleSystemHierarchyEditor()
  8. {
  9. // 注册 Hierarchy 窗口的绘制回调
  10. EditorApplication.hierarchyWindowItemOnGUI += OnHierarchyWindowItemGUI;
  11. }
  12. private static void OnHierarchyWindowItemGUI(int instanceID, Rect selectionRect)
  13. {
  14. // 获取当前绘制的 GameObject
  15. GameObject obj = EditorUtility.InstanceIDToObject(instanceID) as GameObject;
  16. if (obj == null) return;
  17. // 检查是否包含 ParticleSystem 和 ParticleSystemRenderer
  18. ParticleSystem particleSystem = obj.GetComponent<ParticleSystem>();
  19. ParticleSystemRenderer particleRenderer = obj.GetComponent<ParticleSystemRenderer>();
  20. if (particleSystem == null || particleRenderer == null) return;
  21. // 设置绘制区域(Hierarchy 右侧)
  22. Rect rect = new Rect(selectionRect);
  23. rect.x += rect.width - 150; // 调整位置,留出空间显示控件
  24. rect.height = EditorGUIUtility.singleLineHeight;
  25. // 显示当前 Sorting Layer 名称(只读)
  26. rect.width = 60; // 层名称显示宽度
  27. GUIStyle labelStyle = new GUIStyle(EditorStyles.label) { fontSize = 10 };
  28. EditorGUI.LabelField(rect, particleRenderer.sortingLayerName, labelStyle);
  29. // 显示当前 Sorting Order 数值(只读)
  30. rect.x += rect.width + 5;
  31. rect.width = 30; // 数值显示宽度
  32. EditorGUI.LabelField(rect, particleRenderer.sortingOrder.ToString(), labelStyle);
  33. // 绘制“+”按钮
  34. rect.x += rect.width + 5;
  35. rect.width = 20; // 按钮宽度
  36. if (GUI.Button(rect, "+"))
  37. {
  38. RecordPrefabChange(particleRenderer, obj, "Increment Particle System Sorting Order");
  39. particleRenderer.sortingOrder += 1;
  40. MarkDirty(particleRenderer, obj);
  41. Debug.Log($"Incremented Sorting Order of {obj.name} to {particleRenderer.sortingOrder}");
  42. }
  43. // 绘制“-”按钮
  44. rect.x += rect.width + 2;
  45. rect.width = 20; // 按钮宽度
  46. if (GUI.Button(rect, "-"))
  47. {
  48. RecordPrefabChange(particleRenderer, obj, "Decrement Particle System Sorting Order");
  49. particleRenderer.sortingOrder -= 1;
  50. MarkDirty(particleRenderer, obj);
  51. Debug.Log($"Decremented Sorting Order of {obj.name} to {particleRenderer.sortingOrder}");
  52. }
  53. }
  54. // 记录预制件修改,支持 Undo
  55. private static void RecordPrefabChange(Object target, GameObject obj, string undoMessage)
  56. {
  57. Undo.RecordObject(target, undoMessage);
  58. // 如果在预制件编辑模式中,记录预制件根对象的修改
  59. if (PrefabStageUtility.GetCurrentPrefabStage() != null)
  60. {
  61. var prefabStage = PrefabStageUtility.GetCurrentPrefabStage();
  62. if (prefabStage.prefabContentsRoot == obj || obj.transform.IsChildOf(prefabStage.prefabContentsRoot.transform))
  63. {
  64. Undo.RecordObject(prefabStage.prefabContentsRoot, undoMessage);
  65. }
  66. }
  67. }
  68. // 标记对象为脏,确保修改保存
  69. private static void MarkDirty(Object target, GameObject obj)
  70. {
  71. EditorUtility.SetDirty(target);
  72. EditorUtility.SetDirty(obj);
  73. // 如果在预制件编辑模式中,保存预制件
  74. if (PrefabStageUtility.GetCurrentPrefabStage() != null)
  75. {
  76. var prefabStage = PrefabStageUtility.GetCurrentPrefabStage();
  77. if (prefabStage.prefabContentsRoot == obj || obj.transform.IsChildOf(prefabStage.prefabContentsRoot.transform))
  78. {
  79. PrefabUtility.SavePrefabAsset(prefabStage.prefabContentsRoot);
  80. }
  81. }
  82. }
  83. }