| using UnityEngine; | 
| using UnityEngine.UI; | 
|   | 
| /// <summary> | 
| /// 特效穿透阻挡器 | 
| /// 将此脚本挂在特效游戏对象上,可以防止特效穿透UI界面 | 
| /// </summary> | 
| public class EffectPenetrationBlocker : MonoBehaviour | 
| { | 
|     [Tooltip("是否在UI层级下自动调整排序顺序")] | 
|     public bool autoAdjustSorting = true; | 
|      | 
|     [Tooltip("特效渲染器,如果为空则自动获取")] | 
|     public Renderer[] effectRenderers; | 
|      | 
|     [Tooltip("特效粒子系统,如果为空则自动获取")] | 
|     public ParticleSystem[] particleSystems; | 
|      | 
|     [Tooltip("自定义排序顺序,仅在不自动调整时有效")] | 
|     public int customSortingOrder = 0; | 
|      | 
|     [Tooltip("自定义排序层,为空则使用默认UI层")] | 
|     public string customSortingLayer = "UI"; | 
|      | 
|     [Tooltip("特效所属的Canvas,如果为空则查找父级Canvas")] | 
|     public Canvas parentCanvas; | 
|      | 
|     [Tooltip("特效在Canvas中的排序偏移量")] | 
|     public int sortingOrderOffset = 1; | 
|      | 
|     private int canvasSortingOrder = 0; | 
|      | 
|     private void Awake() | 
|     { | 
|         // 如果没有指定渲染器,则自动获取 | 
|         if (effectRenderers == null || effectRenderers.Length == 0) | 
|         { | 
|             effectRenderers = GetComponentsInChildren<Renderer>(true); | 
|         } | 
|          | 
|         // 如果没有指定粒子系统,则自动获取 | 
|         if (particleSystems == null || particleSystems.Length == 0) | 
|         { | 
|             particleSystems = GetComponentsInChildren<ParticleSystem>(true); | 
|         } | 
|          | 
|         // 查找父级Canvas | 
|         if (parentCanvas == null) | 
|         { | 
|             parentCanvas = GetComponentInParent<Canvas>(); | 
|         } | 
|          | 
|         if (autoAdjustSorting) | 
|         { | 
|             UpdateSortingOrder(); | 
|         } | 
|         else | 
|         { | 
|             // 使用自定义排序 | 
|             ApplySortingSettings(customSortingOrder, customSortingLayer); | 
|         } | 
|     } | 
|      | 
|     private void OnEnable() | 
|     { | 
|         if (autoAdjustSorting) | 
|         { | 
|             UpdateSortingOrder(); | 
|         } | 
|     } | 
|      | 
|     /// <summary> | 
|     /// 更新排序顺序,确保特效显示在当前UI界面上方 | 
|     /// </summary> | 
|     public void UpdateSortingOrder() | 
|     { | 
|         if (!autoAdjustSorting) return; | 
|          | 
|         // 获取父级Canvas的排序顺序 | 
|         if (parentCanvas != null) | 
|         { | 
|             canvasSortingOrder = parentCanvas.sortingOrder; | 
|         } | 
|         else | 
|         { | 
|             // 如果没有找到父级Canvas,则使用默认值 | 
|             canvasSortingOrder = 0; | 
|         } | 
|          | 
|         // 将特效的排序顺序设置为Canvas排序顺序加上偏移量 | 
|         ApplySortingSettings(canvasSortingOrder + sortingOrderOffset, customSortingLayer); | 
|     } | 
|      | 
|     /// <summary> | 
|     /// 应用排序设置到所有渲染器和粒子系统 | 
|     /// </summary> | 
|     private void ApplySortingSettings(int sortingOrder, string sortingLayer) | 
|     { | 
|         // 应用到渲染器 | 
|         foreach (Renderer renderer in effectRenderers) | 
|         { | 
|             if (renderer != null) | 
|             { | 
|                 renderer.sortingOrder = sortingOrder; | 
|                 if (!string.IsNullOrEmpty(sortingLayer)) | 
|                 { | 
|                     renderer.sortingLayerName = sortingLayer; | 
|                 } | 
|             } | 
|         } | 
|          | 
|         // 应用到粒子系统 | 
|         foreach (ParticleSystem ps in particleSystems) | 
|         { | 
|             if (ps != null) | 
|             { | 
|                 ParticleSystemRenderer psRenderer = ps.GetComponent<ParticleSystemRenderer>(); | 
|                 if (psRenderer != null) | 
|                 { | 
|                     psRenderer.sortingOrder = sortingOrder; | 
|                     if (!string.IsNullOrEmpty(sortingLayer)) | 
|                     { | 
|                         psRenderer.sortingLayerName = sortingLayer; | 
|                     } | 
|                 } | 
|             } | 
|         } | 
|     } | 
|      | 
|     /// <summary> | 
|     /// 手动设置排序顺序 | 
|     /// </summary> | 
|     public void SetSortingOrder(int sortingOrder, string sortingLayer = null) | 
|     { | 
|         customSortingOrder = sortingOrder; | 
|         if (!string.IsNullOrEmpty(sortingLayer)) | 
|         { | 
|             customSortingLayer = sortingLayer; | 
|         } | 
|          | 
|         autoAdjustSorting = false; | 
|         ApplySortingSettings(customSortingOrder, customSortingLayer); | 
|     } | 
|      | 
|     /// <summary> | 
|     /// 设置父级Canvas | 
|     /// </summary> | 
|     public void SetParentCanvas(Canvas canvas) | 
|     { | 
|         parentCanvas = canvas; | 
|         if (autoAdjustSorting) | 
|         { | 
|             UpdateSortingOrder(); | 
|         } | 
|     } | 
| } |