| | |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using Spine.Unity; |
| | | using UnityEngine; |
| | | using UnityEngine.UI; |
| | | |
| | | |
| | | |
| | | /// <summary> |
| | | /// 特效穿透阻挡器 |
| | |
| | | { |
| | | [Tooltip("是否在UI层级下自动调整排序顺序")] |
| | | public bool autoAdjustSorting = true; |
| | | |
| | | |
| | | [Tooltip("特效渲染器,如果为空则自动获取")] |
| | | public Renderer[] effectRenderers; |
| | | |
| | | [Tooltip("特效粒子系统,如果为空则自动获取")] |
| | | public ParticleSystem[] particleSystems; |
| | | |
| | | public List<Renderer> effectRenderers = new List<Renderer>(); |
| | | |
| | | [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 sortingOrderOffset = 1; |
| | | |
| | | public int canvasSortingOrder = 0; |
| | | |
| | | |
| | | public int renderQueue = 3000;//默认值 |
| | | |
| | | public Action<string, int> onSortingChanged; |
| | | |
| | | private void Awake() |
| | | { |
| | | transform.GetComponentsInChildren(true, effectRenderers); |
| | | |
| | | // 如果没有指定渲染器,则自动获取 |
| | | if (effectRenderers == null || effectRenderers.Length == 0) |
| | | if (effectRenderers == null || effectRenderers.Count == 0) |
| | | { |
| | | effectRenderers = GetComponentsInChildren<Renderer>(true); |
| | | transform.GetComponentsInChildren<Renderer>(true, effectRenderers); |
| | | } |
| | | |
| | | // 如果没有指定粒子系统,则自动获取 |
| | | if (particleSystems == null || particleSystems.Length == 0) |
| | | { |
| | | particleSystems = GetComponentsInChildren<ParticleSystem>(true); |
| | | } |
| | | |
| | | |
| | | // 查找父级Canvas |
| | | if (parentCanvas == null) |
| | | { |
| | | parentCanvas = GetComponentInParent<Canvas>(); |
| | | } |
| | | |
| | | |
| | | if (autoAdjustSorting) |
| | | { |
| | | UpdateSortingOrder(); |
| | |
| | | ApplySortingSettings(customSortingOrder, customSortingLayer); |
| | | } |
| | | } |
| | | |
| | | |
| | | private void OnEnable() |
| | | { |
| | | if (autoAdjustSorting) |
| | |
| | | UpdateSortingOrder(); |
| | | } |
| | | } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 更新排序顺序,确保特效显示在当前UI界面上方 |
| | | /// </summary> |
| | | public void UpdateSortingOrder() |
| | | { |
| | | if (!autoAdjustSorting) return; |
| | | |
| | | |
| | | // 获取父级Canvas的排序顺序 |
| | | if (parentCanvas != null) |
| | | { |
| | |
| | | // 如果没有找到父级Canvas,则使用默认值 |
| | | canvasSortingOrder = 0; |
| | | } |
| | | |
| | | |
| | | // 将特效的排序顺序设置为Canvas排序顺序加上偏移量 |
| | | ApplySortingSettings(canvasSortingOrder + _sortingOrderOffset, customSortingLayer); |
| | | ApplySortingSettings(canvasSortingOrder + sortingOrderOffset, customSortingLayer); |
| | | } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 应用排序设置到所有渲染器和粒子系统 |
| | | /// </summary> |
| | |
| | | if (renderer != null) |
| | | { |
| | | renderer.sortingOrder = sortingOrder; |
| | | renderer.material.renderQueue = renderQueue; // 设置渲染队列 |
| | | // renderer.material.renderQueue = overlayRQ; |
| | | if (!string.IsNullOrEmpty(sortingLayer)) |
| | | { |
| | |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 应用到粒子系统 |
| | | foreach (ParticleSystem ps in particleSystems) |
| | | { |
| | | if (ps != null) |
| | | { |
| | | ParticleSystemRenderer psRenderer = ps.GetComponent<ParticleSystemRenderer>(); |
| | | if (psRenderer != null) |
| | | { |
| | | psRenderer.sortingOrder = sortingOrder; |
| | | // psRenderer.material.renderQueue = overlayRQ; |
| | | if (!string.IsNullOrEmpty(sortingLayer)) |
| | | { |
| | | psRenderer.sortingLayerName = sortingLayer; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | onSortingChanged?.Invoke(sortingLayer, sortingOrder); |
| | | } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 手动设置排序顺序 |
| | | /// </summary> |
| | |
| | | { |
| | | customSortingLayer = sortingLayer; |
| | | } |
| | | |
| | | |
| | | autoAdjustSorting = false; |
| | | ApplySortingSettings(customSortingOrder, customSortingLayer); |
| | | } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 设置父级Canvas |
| | | /// </summary> |
| | |
| | | parentCanvas = canvas; |
| | | if (autoAdjustSorting) |
| | | { |
| | | UpdateSortingOrder(); |
| | | this.DelayFrame(UpdateSortingOrder); |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 应用遮罩区域(RectTransform),可用于裁剪特效 |
| | | /// </summary> |
| | | public void PerformMask(RectTransform maskRect) |
| | | { |
| | | // 这里只是示例,实际可根据你的Shader或特效材质做裁剪 |
| | | foreach (Renderer renderer in effectRenderers) |
| | | { |
| | | if (renderer != null && renderer.material != null && maskRect != null) |
| | | { |
| | | Vector3[] corners = new Vector3[4]; |
| | | maskRect.GetWorldCorners(corners); |
| | | Vector4 clipRect = new Vector4(corners[0].x, corners[0].y, corners[2].x, corners[2].y); |
| | | renderer.material.SetVector("_ClipRect", clipRect); |
| | | renderer.material.SetFloat("_UseClipRect", 1); |
| | | } |
| | | else if (renderer != null && renderer.material != null) |
| | | { |
| | | renderer.material.SetFloat("_UseClipRect", 0); |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | #if UNITY_EDITOR |
| | | [ContextMenu("Apply")] |
| | | public void Apply() |