控制特效在UI上面
控制特效在UI上,需要改动两个地方:
1、渲染队列为透明
2、保证sorting layer正确
如下代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine.CFEventSystems;
namespace UnityEngine.CFUI
{
public class CFParticleControl : UIBehaviour
{
[SerializeField]
public int renderQueueOffset = 0;
public int renderQueue = 3000;
public Renderer[] renderers;
public Canvas mCanvas;
public CFRectMask2D mCurrentMask;
private bool running = false;
public void Render(bool reset = true, bool atOnce = false)
{
if (!isActiveAndEnabled) return;
running = true;
if (atOnce)
Update();
}
private void ReInitialize()
{
renderers = GetRenderers();
mCanvas = GetFatherCanvas();
mCurrentMask = GetClippable();
}
private void RenderSorting()
{
if (mCanvas == null) return;
if (renderers != null)
{
for (int i = 0; i < renderers.Length; ++i)
{
renderers[i].sortingLayerID = mCanvas.sortingLayerID;
renderers[i].sortingLayerName = mCanvas.sortingLayerName;
renderers[i].sortingOrder = mCanvas.sortingOrder;
renderers[i].enabled = mCanvas.enabled;
if (Application.isPlaying)
{
InnterUpdate(renderers[i].material);
}
else
{
InnterUpdate(renderers[i].sharedMaterial);
}
}
}
}
private Renderer[] GetRenderers()
{
return transform.GetComponentsInChildren<Renderer>(true);
}
private Canvas GetFatherCanvas()
{
List<Canvas> list = ListPool<Canvas>.Get();
transform.GetComponentsInParent(true, list);
Canvas returnCanvas = null;
if (list.Count > 0) returnCanvas = list[0];
ListPool<Canvas>.Release(list);
return returnCanvas;
}
private CFRectMask2D GetClippable()
{
List<CFRectMask2D> components = ListPool<CFRectMask2D>.Get();
transform.GetComponentsInParent(true, components);
CFRectMask2D mask = null;
if (components.Count > 0) mask = components[0];
ListPool<CFRectMask2D>.Release(components);
return mask;
}
private void InnterUpdate(Material material)
{
if (material == null) return;
if (material.renderQueue != renderQueue + renderQueueOffset)
{
material.renderQueue = renderQueue + renderQueueOffset;
}
}
protected override void OnEnable()
{
base.OnEnable();
Render(false);
}
protected override void OnDisable()
{
base.OnDisable();
mCanvas = null;
mCurrentMask = null;
renderers = null;
}
private void Update()
{
if (!running) return;
running = false;
ReInitialize();
RenderSorting();
RenderClippable();
}
protected override void OnCanvasHierarchyChanged()
{
running = true;
}
protected override void OnRectTransformDimensionsChange()
{
running = true;
}
protected override void OnTransformParentChanged()
{
running = true;
}
protected override void OnDidApplyAnimationProperties()
{
running = true;
}
readonly Vector3[] corners = new Vector3[4];
private Vector4 border = new Vector4();
private void RenderClippable()
{
if (renderers == null) return;
if (mCurrentMask == null)
{
for (int i = 0; i < renderers.Length; ++i)
{
if (renderers[i].material == null) continue;
renderers[i].material.DisableKeyword("UNITY_UI_CLIP_RECT");
border.Set(0, 0, 0, 0);
}
}
else
{
for (int i = 0; i < renderers.Length; ++i)
{
if (renderers[i].material == null) continue;
mCurrentMask.rectTransform.GetWorldCorners(corners);
renderers[i].material.EnableKeyword("UNITY_UI_CLIP_RECT");
border.Set(corners[0].x, corners[0].y, corners[2].x, corners[2].y);
}
}
}
}
}
关键代码在:
renderers[i].sortingLayerID = mCanvas.sortingLayerID;
renderers[i].sortingLayerName = mCanvas.sortingLayerName;
renderers[i].sortingOrder = mCanvas.sortingOrder;
无论是使用mesh的特效,还是使用particleSystem的特效,最终获取render即可。
注意:PartcileSystem的render获取到的是ParticleSystemRender。但ParticleSystemRender是Render的子类,所以也能获取的到。