using UnityEngine; using UnityEngine.UI; /// /// 特效穿透阻挡器 /// 将此脚本挂在特效游戏对象上,可以防止特效穿透UI界面 /// 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 = 0; public int canvasSortingOrder = 0; private void Awake() { // 如果没有指定渲染器,则自动获取 if (effectRenderers == null || effectRenderers.Length == 0) { effectRenderers = GetComponentsInChildren(true); } // 如果没有指定粒子系统,则自动获取 if (particleSystems == null || particleSystems.Length == 0) { particleSystems = GetComponentsInChildren(true); } // 查找父级Canvas if (parentCanvas == null) { parentCanvas = GetComponentInParent(); } if (autoAdjustSorting) { UpdateSortingOrder(); } else { // 使用自定义排序 ApplySortingSettings(customSortingOrder, customSortingLayer); } } private void OnEnable() { if (autoAdjustSorting) { UpdateSortingOrder(); } } /// /// 更新排序顺序,确保特效显示在当前UI界面上方 /// public void UpdateSortingOrder() { if (!autoAdjustSorting) return; // 获取父级Canvas的排序顺序 if (parentCanvas != null) { canvasSortingOrder = parentCanvas.sortingOrder; } else { // 如果没有找到父级Canvas,则使用默认值 canvasSortingOrder = 0; } // 将特效的排序顺序设置为Canvas排序顺序加上偏移量 ApplySortingSettings(canvasSortingOrder + _sortingOrderOffset, customSortingLayer); } /// /// 应用排序设置到所有渲染器和粒子系统 /// private void ApplySortingSettings(int sortingOrder, string sortingLayer) { // const int overlayRQ = 4000; // 应用到渲染器 foreach (Renderer renderer in effectRenderers) { if (renderer != null) { renderer.sortingOrder = sortingOrder; // renderer.material.renderQueue = overlayRQ; if (!string.IsNullOrEmpty(sortingLayer)) { renderer.sortingLayerName = sortingLayer; } } } // 应用到粒子系统 foreach (ParticleSystem ps in particleSystems) { if (ps != null) { ParticleSystemRenderer psRenderer = ps.GetComponent(); if (psRenderer != null) { psRenderer.sortingOrder = sortingOrder; // psRenderer.material.renderQueue = overlayRQ; if (!string.IsNullOrEmpty(sortingLayer)) { psRenderer.sortingLayerName = sortingLayer; } } } } } /// /// 手动设置排序顺序 /// public void SetSortingOrder(int sortingOrder, string sortingLayer = null) { customSortingOrder = sortingOrder; if (!string.IsNullOrEmpty(sortingLayer)) { customSortingLayer = sortingLayer; } autoAdjustSorting = false; ApplySortingSettings(customSortingOrder, customSortingLayer); } /// /// 设置父级Canvas /// public void SetParentCanvas(Canvas canvas) { parentCanvas = canvas; if (autoAdjustSorting) { UpdateSortingOrder(); } } #if UNITY_EDITOR [ContextMenu("Apply")] public void Apply() { UpdateSortingOrder(); } #endif }