这里接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. oracle No more data to read from socket之ora-07445排查解决

    今天下午,原来一个部门的同事找过来,说有个即将上线的环境偶尔会出现 No more data to read from socket错误,版本是oracle 11.2.0.1,如下: 经查,这个问题原 ...

  2. python简说(二十七)sys.argv

    sys.argv,是获取到运行python文件的时候传入的参数 可以在pycharm中点击 if len(sys.argv)>1: if sys.argv[1]=='--help': quit( ...

  3. 播放器smplayer的各种键盘快捷键

    smplayer的很多键盘快捷键都是 "单字母"命令. 如: f, m命令等 有主工具栏, 是通过F5来进行切换的, 但是单击f5后"可能"会使窗口失去焦点, ...

  4. CodeForces 430A Points and Segments (easy)(构造)题解

    题意:之前愣是没看懂题意...就是给你n个点的坐标xi,然后还规定了Li,Ri,要求给每个点染色,每一组L,R内的点红色和黑色的个数不能相差大于1个,问你能不能染成功,不能输出-1,能就按照输入的顺序 ...

  5. svn强制commit写log

    https://tortoisesvn.net/docs/nightly/TortoiseSVN_en/tsvn-howto-minlogmsgsize.html Force users to ent ...

  6. Elasticsearch查询Index以及删除

    查询Index信息 GET /bank HTTP/1.1Host: localhost:9200 { "bank": { "aliases": {}, &quo ...

  7. 数据集是 seq 文件的处理办法

    数据集是 seq 文件的处理办法 2017-03-17 最近下了一个数据集,是 seq 格式的,第一次处理这种数据.使用了官方提供的 matlab 工具包:https://pdollar.github ...

  8. 用yarn代替cnpm,cnpm漏包有点严重

    npm 的方式  npm  install  -g  yarn   安装完成后,你可以测试下自己的版本 yarn --version 开始使用 单独安装包的方式add 不是install,后面不用加 ...

  9. JavaWeb--简单分页技术

    分页需要的技术点:1.前台分页标签的使用 2.前台上一页,下一页显示的业务逻辑 3.MSQL用到的语句  limit 4.封装pageBean对象 这个是PageBean用到的 分页公式: int t ...

  10. Luncene学习 第一天 《入门程序》

    整个luncene 流程 下面贴出代码 package com.zuoyan.lucene.demo; import java.io.File; import org.apache.commons.i ...