Unity中的粒子特效的 RendererQ 排序
这里接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 排序的更多相关文章
- UGUI中显示粒子特效
今天在UGUI上显示粒子特效的时候遇到的一些问题,Mark一下.原理:修改特效中每一个ParticleSystem的Layer为UI,并且把ParticleSystemRenderer.sorting ...
- Unity:控制粒子特效的移动方向
前几天在项目中遇到一个问题,需求是界面中先展示一段闪光特效,停顿一段时间后特效飞往一个固定的位置然后消失,类似于跑酷游戏吃到金币后金币飞往固定的金币数值显示框那种效果(具体是通过特效来实现还是直接通过 ...
- 关于Unity中的旋涡特效的制作(捕鱼达人3技术)(专题八)
Mesh--材质--Shader 1: Mesh 是网格,包括顶点,法线,纹理坐标,切线,三角形.在每一个3D模型节点里面,有一个Mesh Filter组件来提取模型里面的网格数据;2: Shader ...
- UGUI中粒子特效与UI的遮挡问题
问题背景: 在做主线任务时发现完成任务后的特效显示穿透上面的UI层,不美观,策划不乐意了,抓紧解决下 解决思路: 首先讲下影响渲染顺序的因素: 能够影响渲染顺序的因素有:1.Camera Depth ...
- 关于Unity中粒子效果的使用
粒子效果1: 游戏中会有很炫酷的特效,比如爆炸,水花,火焰等;2: unity提供粒子编辑器,方便特效人员来开发很炫酷的特效;3.粒子效果一般有专门的粒子特效师来做,我们只需要拿来用就好了,很多参数没 ...
- 【Unity 3D】学习笔记四十二:粒子特效
粒子特效 粒子特效的原理是将若干粒子无规则的组合在一起.来模拟火焰,爆炸.水滴,雾气等效果. 要使用粒子特效首先要创建,在hierarchy视图中点击create--particle system就可 ...
- Unity中List的随机排序(乱序)
为什么要给List排序做一个Unity限定条件呢 首先,是C#中的List泛型,若是Java,直接调用Collection.shuffle()就OK了 而Unity的C#版本较低,不能使用Random ...
- Unity中的资源管理
一.AssetBundle 相关 Q1:Unity中的SerializedFile是怎么产生的?请问用Unload(false)可以清除吗?因为读取了Bundle里面的内容后已经赋值给其他物体了.而且 ...
- Mask裁切UI粒子特效或者3D模型
刚好前几天有人问我这个问题,再加上新项目也可能用,所以这两天就研究了一下.其实如果粒子特效 和3D模型 都用RenderTexture来做的话就不会有裁切的问题,但是粒子特效用RenderTextur ...
随机推荐
- org.mybatis.spring.transaction.SpringManagedTransaction.getTimeout() mybatis和spring-mybatis版本不匹配问题
java.lang.AbstractMethodError: org.mybatis.spring.transaction.SpringManagedTransaction.getTimeout() ...
- 安装搭建Python2.* 和3.* 环境详细步骤
Python是跨平台的,它可以运行在Windows.Mac和各种Linux/Unix系统上. 安装Python 首先进入Python官方网站,将Python下载下来. win7安装python 在官网 ...
- 尚硅谷面试第一季-08Spring支持的常用数据库事务传播属性和事务隔离级别
目录结构: 关键代码: BookShopServiceImpl.java package Spring支持的常用数据库事务传播属性和事务隔离级别.tx.service.impl; import Spr ...
- python --- 21 MRO C3算法
一.python2.2之前用的是 经典类的MRO继承 ①深度递归继承 从左到右 ,一条路走到黑 ②广度继承 一层一层的继承 深度继承时 为 R 1 2 3 4 ...
- oracle a:=100 和 b=:c 区别
a:=100 是赋值语句 b=:c :c是一个整体,表示一个参数.
- Ground Defense【不知道叫啥可能就是枚举】
问题 G: Ground Defense 时间限制: 1 Sec 内存限制: 128 MB 提交: 116 解决: 22 [提交] [状态] [命题人:admin] 题目描述 You are a ...
- aria2的下载配置
aria2的命令行命令是: aria2c 一种方式: aria2c "http://host/file.zip" 如同wget 第二种方式: rpc server方式:
- SpringBoot 使用Druid连接池
1.pom依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId> ...
- Jmeter工具
开源,纯java,用于HTTP协议性能测试,接口协议测试工具,自动化测试工具 功能测试角度: 1.支持多种不同类型的协议.接口协议有多种 2.可以全面支持HTTP协议(后台交互) 3.其他非直接支持的 ...
- JS加载获取父窗体传递的参数
JS加载获取父窗体传递的参数 $(document).ready(function () { var query = location.search.substring(1); var values ...