|  | @@ -0,0 +1,93 @@
 | 
	
		
			
				|  |  | +using UnityEngine;
 | 
	
		
			
				|  |  | +using UnityEditor;
 | 
	
		
			
				|  |  | +using UnityEditor.SceneManagement;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +[InitializeOnLoad]
 | 
	
		
			
				|  |  | +public class ParticleSystemHierarchyEditor
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +    static ParticleSystemHierarchyEditor()
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +        // 注册 Hierarchy 窗口的绘制回调
 | 
	
		
			
				|  |  | +        EditorApplication.hierarchyWindowItemOnGUI += OnHierarchyWindowItemGUI;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    private static void OnHierarchyWindowItemGUI(int instanceID, Rect selectionRect)
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +        // 获取当前绘制的 GameObject
 | 
	
		
			
				|  |  | +        GameObject obj = EditorUtility.InstanceIDToObject(instanceID) as GameObject;
 | 
	
		
			
				|  |  | +        if (obj == null) return;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // 检查是否包含 ParticleSystem 和 ParticleSystemRenderer
 | 
	
		
			
				|  |  | +        ParticleSystem particleSystem = obj.GetComponent<ParticleSystem>();
 | 
	
		
			
				|  |  | +        ParticleSystemRenderer particleRenderer = obj.GetComponent<ParticleSystemRenderer>();
 | 
	
		
			
				|  |  | +        if (particleSystem == null || particleRenderer == null) return;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // 设置绘制区域(Hierarchy 右侧)
 | 
	
		
			
				|  |  | +        Rect rect = new Rect(selectionRect);
 | 
	
		
			
				|  |  | +        rect.x += rect.width - 150; // 调整位置,留出空间显示控件
 | 
	
		
			
				|  |  | +        rect.height = EditorGUIUtility.singleLineHeight;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // 显示当前 Sorting Layer 名称(只读)
 | 
	
		
			
				|  |  | +        rect.width = 60; // 层名称显示宽度
 | 
	
		
			
				|  |  | +        GUIStyle labelStyle = new GUIStyle(EditorStyles.label) { fontSize = 10 };
 | 
	
		
			
				|  |  | +        EditorGUI.LabelField(rect, particleRenderer.sortingLayerName, labelStyle);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // 显示当前 Sorting Order 数值(只读)
 | 
	
		
			
				|  |  | +        rect.x += rect.width + 5;
 | 
	
		
			
				|  |  | +        rect.width = 30; // 数值显示宽度
 | 
	
		
			
				|  |  | +        EditorGUI.LabelField(rect, particleRenderer.sortingOrder.ToString(), labelStyle);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // 绘制“+”按钮
 | 
	
		
			
				|  |  | +        rect.x += rect.width + 5;
 | 
	
		
			
				|  |  | +        rect.width = 20; // 按钮宽度
 | 
	
		
			
				|  |  | +        if (GUI.Button(rect, "+"))
 | 
	
		
			
				|  |  | +        {
 | 
	
		
			
				|  |  | +            RecordPrefabChange(particleRenderer, obj, "Increment Particle System Sorting Order");
 | 
	
		
			
				|  |  | +            particleRenderer.sortingOrder += 1;
 | 
	
		
			
				|  |  | +            MarkDirty(particleRenderer, obj);
 | 
	
		
			
				|  |  | +            Debug.Log($"Incremented Sorting Order of {obj.name} to {particleRenderer.sortingOrder}");
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // 绘制“-”按钮
 | 
	
		
			
				|  |  | +        rect.x += rect.width + 2;
 | 
	
		
			
				|  |  | +        rect.width = 20; // 按钮宽度
 | 
	
		
			
				|  |  | +        if (GUI.Button(rect, "-"))
 | 
	
		
			
				|  |  | +        {
 | 
	
		
			
				|  |  | +            RecordPrefabChange(particleRenderer, obj, "Decrement Particle System Sorting Order");
 | 
	
		
			
				|  |  | +            particleRenderer.sortingOrder -= 1;
 | 
	
		
			
				|  |  | +            MarkDirty(particleRenderer, obj);
 | 
	
		
			
				|  |  | +            Debug.Log($"Decremented Sorting Order of {obj.name} to {particleRenderer.sortingOrder}");
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    // 记录预制件修改,支持 Undo
 | 
	
		
			
				|  |  | +    private static void RecordPrefabChange(Object target, GameObject obj, string undoMessage)
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +        Undo.RecordObject(target, undoMessage);
 | 
	
		
			
				|  |  | +        // 如果在预制件编辑模式中,记录预制件根对象的修改
 | 
	
		
			
				|  |  | +        if (PrefabStageUtility.GetCurrentPrefabStage() != null)
 | 
	
		
			
				|  |  | +        {
 | 
	
		
			
				|  |  | +            var prefabStage = PrefabStageUtility.GetCurrentPrefabStage();
 | 
	
		
			
				|  |  | +            if (prefabStage.prefabContentsRoot == obj || obj.transform.IsChildOf(prefabStage.prefabContentsRoot.transform))
 | 
	
		
			
				|  |  | +            {
 | 
	
		
			
				|  |  | +                Undo.RecordObject(prefabStage.prefabContentsRoot, undoMessage);
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    // 标记对象为脏,确保修改保存
 | 
	
		
			
				|  |  | +    private static void MarkDirty(Object target, GameObject obj)
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +        EditorUtility.SetDirty(target);
 | 
	
		
			
				|  |  | +        EditorUtility.SetDirty(obj);
 | 
	
		
			
				|  |  | +        // 如果在预制件编辑模式中,保存预制件
 | 
	
		
			
				|  |  | +        if (PrefabStageUtility.GetCurrentPrefabStage() != null)
 | 
	
		
			
				|  |  | +        {
 | 
	
		
			
				|  |  | +            var prefabStage = PrefabStageUtility.GetCurrentPrefabStage();
 | 
	
		
			
				|  |  | +            if (prefabStage.prefabContentsRoot == obj || obj.transform.IsChildOf(prefabStage.prefabContentsRoot.transform))
 | 
	
		
			
				|  |  | +            {
 | 
	
		
			
				|  |  | +                PrefabUtility.SavePrefabAsset(prefabStage.prefabContentsRoot);
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +}
 |