这里接https://www.cnblogs.com/luguoshuai/p/10021660.html

这里介绍两套粒子排序的方法。

首先声明,这两套排序方法均不是本人所写,是在项目开发的过程当中,看到同事的设计,然后我就记录了下来了,作为后续的学习与使用。

方法一:

 using System.Collections.Generic;
using UnityEngine; public class UIRenderQueueSorter : MonoBehaviour
{
[SerializeField]
UIWidget m_source; //基础RendererQ,粒子的 RendererQ 均是在此基础上递增的
[SerializeField]
int m_offset; //每次递增的幅度
[SerializeField]
List<Renderer> m_renderers = new List<Renderer>(); public void Initialize()
{
Renderer[] renders = transform.GetComponentsInChildren<Renderer>(true);
m_renderers.AddRange(renders);
} void Update()
{
if (m_source && m_renderers.Count > )
{
for (int i = ; i < m_renderers.Count; i++)
{
Renderer r = m_renderers[i];
if (r && r.sharedMaterial && m_source.drawCall != null)
r.sharedMaterial.renderQueue = m_source.drawCall.renderQueue + m_offset;
}
}
} public void AddRenderer(Renderer r)
{
if (!m_renderers.Contains(r))
{
m_renderers.Add(r);
}
} public void ClearAllRenderers()
{
m_renderers.Clear();
} public UIWidget Source
{
set { m_source = value; }
} public int Offset
{
set { m_offset = value; }
}
}

用法介绍,将该脚本挂载到粒子特效的父级对象上,使用的时候,只需要调用一下Initialize()方法即可。

方法二:

这个其实是对NGUI的一个简答扩展,粒子的 RendererQ 是以Panel为单位来计算的

对NGUI的修改,添加如下变量:

     public List<UIParticlesEffectAutoSort> uiEffectList = new List<UIParticlesEffectAutoSort>();

修改NGUI的 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 = , imax = list.Count; i < imax; ++i)
list[i].UpdateSelf(); int rq = ;
int addRq = ; // Update all draw calls, making them draw in the right order
for (int i = , imax = list.Count; i < imax; ++i)
{
UIPanel p = list[i]; if (p.renderQueue == RenderQueue.Automatic)
{
p.startingRenderQueue = rq;
p.UpdateDrawCalls();
rq += p.drawCalls.Count;
addRq = ;
for(int j = ; j < p.uiEffectList.Count; ++j)
{
addRq = Mathf.Max(addRq, p.uiEffectList[j].UpdateRendererQueue(rq));
}
rq += addRq;
}
else if (p.renderQueue == RenderQueue.StartAt)
{
p.UpdateDrawCalls();
if (p.drawCalls.Count != )
rq = Mathf.Max(rq, p.startingRenderQueue + p.drawCalls.Count);
}
else // Explicit
{
p.UpdateDrawCalls();
if (p.drawCalls.Count != )
rq = Mathf.Max(rq, p.startingRenderQueue + );
}
}
}
}

UIParticlesEffectAutoSort:

 using UnityEngine;
using System.Collections.Generic; public class UIParticlesEffectAutoSort : MonoBehaviour
{
protected UIPanel panel;
protected List<Material> mats = new List<Material>();
int beginRenderQ = -, totalRenderQ = ;
void Start()
{
panel = gameObject.GetComponentInParent<UIPanel>();
if (panel == null)
{
enabled = false;
}
else
{
Renderer[] rds = gameObject.GetComponentsInChildren<Renderer>(true);
for (int i = ; i < rds.Length; ++i)
{
for (int j = ; j < rds[i].sharedMaterials.Length; ++j)
{
if (rds[i].sharedMaterials[j] != null)
mats.Add(rds[i].sharedMaterials[j]);
}
}
mats.Sort(delegate(Material a, Material b)
{
return a.renderQueue.CompareTo(b.renderQueue);
});
panel.uiEffectList.Add(this);
}
}
void OnDestroy()
{
if (panel != null)
panel.uiEffectList.Remove(this);
}
public int UpdateRendererQueue(int rq)
{
if (panel == null)
return ;
if (mats.Count > )
{
if (beginRenderQ != rq)
{
beginRenderQ = rq;
int tempRenderQ = -, addRenderQ = ;
for (int i = ; i < mats.Count; ++i)
{
if (mats[i] == null)
continue;
if (tempRenderQ != mats[i].renderQueue)
{
tempRenderQ = mats[i].renderQueue;
++addRenderQ;
}
mats[i].renderQueue = beginRenderQ + addRenderQ;
}
totalRenderQ = addRenderQ + ;
}
return totalRenderQ;
}
return ;
}
}

用法:将该脚本挂载到粒子特效的父级对象上即可。

需要注意的是,这两个方法都是调整的 sharedMaterials,如果在使用的过程中发现粒子的层级不正确,试着调整materials即可。

比如,方法二:

 using System.Collections.Generic;
using UnityEngine; public class UISelfParticalEffectAutoSort : UIParticlesEffectAutoSort
{
void Start()
{
panel = gameObject.GetComponentInParent<UIPanel>();
if (panel == null)
{
enabled = false;
}
else
{
Renderer[] rds = gameObject.GetComponentsInChildren<Renderer>(true);
for (int i = ; i < rds.Length; ++i)
{
for (int j = , jMax = rds[i].materials.Length; j < jMax; ++j)
{
if (rds[i].materials[j] != null)
mats.Add(rds[i].materials[j]);
}
}
mats.Sort(delegate(Material a, Material b)
{
return a.renderQueue.CompareTo(b.renderQueue);
});
panel.uiEffectList.Add(this);
}
}
void OnDestroy()
{
if (panel != null)
panel.uiEffectList.Remove(this);
for (int i = mats.Count - ; i >= ; --i)
GameObject.Destroy(mats[i]);
mats.Clear();
}
}

主要看Start方法。

Unity中的粒子特效的 RendererQ 排序的更多相关文章

  1. UGUI中显示粒子特效

    今天在UGUI上显示粒子特效的时候遇到的一些问题,Mark一下.原理:修改特效中每一个ParticleSystem的Layer为UI,并且把ParticleSystemRenderer.sorting ...

  2. Unity:控制粒子特效的移动方向

    前几天在项目中遇到一个问题,需求是界面中先展示一段闪光特效,停顿一段时间后特效飞往一个固定的位置然后消失,类似于跑酷游戏吃到金币后金币飞往固定的金币数值显示框那种效果(具体是通过特效来实现还是直接通过 ...

  3. 关于Unity中的旋涡特效的制作(捕鱼达人3技术)(专题八)

    Mesh--材质--Shader 1: Mesh 是网格,包括顶点,法线,纹理坐标,切线,三角形.在每一个3D模型节点里面,有一个Mesh Filter组件来提取模型里面的网格数据;2: Shader ...

  4. UGUI中粒子特效与UI的遮挡问题

    问题背景: 在做主线任务时发现完成任务后的特效显示穿透上面的UI层,不美观,策划不乐意了,抓紧解决下 解决思路: 首先讲下影响渲染顺序的因素: 能够影响渲染顺序的因素有:1.Camera Depth  ...

  5. 关于Unity中粒子效果的使用

    粒子效果1: 游戏中会有很炫酷的特效,比如爆炸,水花,火焰等;2: unity提供粒子编辑器,方便特效人员来开发很炫酷的特效;3.粒子效果一般有专门的粒子特效师来做,我们只需要拿来用就好了,很多参数没 ...

  6. 【Unity 3D】学习笔记四十二:粒子特效

    粒子特效 粒子特效的原理是将若干粒子无规则的组合在一起.来模拟火焰,爆炸.水滴,雾气等效果. 要使用粒子特效首先要创建,在hierarchy视图中点击create--particle system就可 ...

  7. Unity中List的随机排序(乱序)

    为什么要给List排序做一个Unity限定条件呢 首先,是C#中的List泛型,若是Java,直接调用Collection.shuffle()就OK了 而Unity的C#版本较低,不能使用Random ...

  8. Unity中的资源管理

    一.AssetBundle 相关 Q1:Unity中的SerializedFile是怎么产生的?请问用Unload(false)可以清除吗?因为读取了Bundle里面的内容后已经赋值给其他物体了.而且 ...

  9. Mask裁切UI粒子特效或者3D模型

    刚好前几天有人问我这个问题,再加上新项目也可能用,所以这两天就研究了一下.其实如果粒子特效 和3D模型 都用RenderTexture来做的话就不会有裁切的问题,但是粒子特效用RenderTextur ...

随机推荐

  1. eclipse maven Errors while generating javadoc on java8

    With JDK 8, we are unable to get Javadoc unless your tool meets the standards of doclint. Some of it ...

  2. 百度uid-generator源码

    https://github.com/baidu/uid-generator snowflake算法 uid-generator是基于Twitter开源的snowflake算法实现的. snowfla ...

  3. mint-ui之Loadmore使用

    <template> <div class="page-loadmore"> <div class="page-loadmore-wrapp ...

  4. Babel总结

    什么是babel? babel是一个JavaScript编译器. Babel是一个工具链,主要用于将ECMAScript 2015+代码转换为向后兼容的旧浏览器或环境中JavaScript版本. 注解 ...

  5. 1.多表查询 => 转化为一张联合大表 2.可视化工具 3.pymysql模块

    多表数据 create table dep( id int primary key auto_increment, name varchar(16), work varchar(16) ); crea ...

  6. Python3 tkinter基础 Checkbutton anchor for生成多个控件并西对齐

             Python : 3.7.0          OS : Ubuntu 18.04.1 LTS         IDE : PyCharm 2018.2.4       Conda ...

  7. luogu1387 最大正方形

    P1387 最大正方形 正方形O(n) 题目描述 在一个n*m的只包含0和1的矩阵里找出一个不包含0的最大正方形,输出边长. 输入输出格式 输入格式: 输入文件第一行为两个整数n,m(1<=n, ...

  8. (转)mblog解读(一)

    (二期)11.开源博客项目mblog解读(一) [课程11]图片上传模块.xmind54.6KB [课程11]消息发...通知.xmind55.2KB [课程11]异常处理分析.xmind95.4KB ...

  9. powershell的stable和preview版本

    在看https://github.com/PowerShell/PowerShell/releases的时候发现,已经发布了6.2.0的preview版本的情况下,还会继续发布6.1.3. 在Read ...

  10. Trimmomatic过滤Illumina低质量序列

    1. 下载安装 直接去官网下载二进制软件,解压后的trimmomatic-0.36.jar即为我们需要的软件 官网: http://www.usadellab.org/cms/index.php?pa ...