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 = 0;
|
|
public 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)
|
{
|
// 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<ParticleSystemRenderer>();
|
if (psRenderer != null)
|
{
|
psRenderer.sortingOrder = sortingOrder;
|
// psRenderer.material.renderQueue = overlayRQ;
|
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();
|
}
|
}
|
|
#if UNITY_EDITOR
|
[ContextMenu("Apply")]
|
public void Apply()
|
{
|
UpdateSortingOrder();
|
}
|
#endif
|
}
|