在UI界面使用一些特效例如宝箱打开的特效,但是2D特效直接在使用上就可以实现层级管理,但有些效果2D达不到的。
之前项目中管理特效的方法是,把这个特效RenderQueue值改为3500,也不太懂为什么,问别的同事说是UIPanel管理有,在Debug状态下看到
红框里是3000的值。这个方法实现了效果,缺点是有多个panel的时候数值需要改到5000,当然但出现多个界面同时存在的时候问题就更大了。数值不知道填什么。
写了
UiFxSort.cs
using System;
using UnityEngine;
using System.Collections;
public class UiFxSort : MonoBehaviour
{
internal UIPanel UiPanel;
public UIWidget UiWidgetInfrontOfMe;
public bool AddQueue = true;
private Renderer[] _renderers;
private void Awake()
{
_renderers = this.GetComponentsInChildren<Renderer>(true);
}
public void InitPanel(UIPanel p)
{
UiPanel = p;
}
private void Start()
{
UiPanel = NGUITools.FindInParents<UIPanel>(gameObject);
UiPanel.AddUiSort(this);
}
public void UpdateSortUi()
{
if (UiWidgetInfrontOfMe != null && UiWidgetInfrontOfMe.drawCall != null)
{
int rq = UiWidgetInfrontOfMe.drawCall.renderQueue + 1;
if (!AddQueue) rq -= 2;
for (int i = 0; i < _renderers.Length; i++)
{
Renderer _renderer = _renderers[i];
if(_renderer==null) return;
if(_renderer.materials ==null) return;
if(_renderer.materials.Length==0) return;
foreach (Material mat in _renderer.materials)
{
if (mat.renderQueue != rq)
{
mat.renderQueue = rq;
}
}
}
}
}
private void OnDestory()
{
if (UiPanel != null) UiPanel.RemoveUiSort(this);
}
}
同时修改了NGUI的UIPanel的LateUpdate方法,添加个新方法
void LateUpdate ()
{
#if UNITY_EDITOR
if (mUpdateFrame != Time.frameCount || !Application.isPlaying)
#else
if (mUpdateFrame != Time.frameCount)
#endif
{
mUpdateFrame = Time.frameCount;
// Update each panel in order
for (int i = 0, imax = list.Count; i < imax; ++i)
list[i].UpdateSelf();
int rq = 3000;
// Update all draw calls, making them draw in the right order
for (int i = 0, imax = list.Count; i < imax; ++i)
{
UIPanel p = list[i];
if (p.renderQueue == RenderQueue.Automatic)
{
p.startingRenderQueue = rq;
p.UpdateDrawCalls();
//rq += p.drawCalls.Count;
//用于粒子混排
rq += p.drawCalls.Count*2;
}
else if (p.renderQueue == RenderQueue.StartAt)
{
p.UpdateDrawCalls();
if (p.drawCalls.Count != 0)
{
//rq = Mathf.Max(rq, p.startingRenderQueue + p.drawCalls.Count);
//用于粒子混排
rq = Mathf.Max(rq, p.startingRenderQueue + p.drawCalls.Count*2);
}
}
else // Explicit
{
p.UpdateDrawCalls();
if (p.drawCalls.Count != 0)
{
//rq = Mathf.Max(rq, p.startingRenderQueue + 1);
//用于粒子混排
rq = Mathf.Max(rq, p.startingRenderQueue + 2);
}
}
p.UpdateUiSort();
}
}
}
//用于粒子混排
List<UiFxSort> container = new List<UiFxSort>();
public void AddUiSort(UiFxSort uiSort)
{
if (container.Contains(uiSort))
{
return;
}
container.Add(uiSort);
}
public void RemoveUiSort(UiFxSort uisSort)
{
container.Remove(uisSort);
}
public void UpdateUiSort()
{
for (int i = 0; i < container.Count; i++)
{
container[i].UpdateSortUi();
}
}
在特效上挂上这个脚本,指点下在界面widget 之前就能解决问题了。
注:局限性这个方法不能解决UIScrollView上特效穿投,特别在超出显示区域的问题。
预告下期内容如何在UI3D特效动态加载。