找回密码
 立即注册
查看: 589|回复: 0

【unity游戏开发】UI粒子特效遮挡问题解决

[复制链接]
发表于 2021-1-7 09:21 | 显示全部楼层 |阅读模式
前言
游戏开发过程中,肯定有特效的存在,一旦在UI上用到了粒子特效,就会存在粒子特效穿透UI的问题,原本应该在底层的粒子特效,穿透到上层的ui之上
解决方案

一. 使用Sorting order
给需要修改层级的ui添加Canvas,
勾选override sorting(禁用Canvas的特殊排序)。
设置 sortingOrder
    底层UI 设置了sortingOrder=0 (可以不设置,因为默认所有UI的Order都是0)ParticleSystem 设置了sortingOrder=1 顶层UI 设置了sortingOrder=2
所以效果是,顶层UI 挡住 ParticleSystem 挡住 底层UI
sortingOrder只是透明物体排序时的一个权重值,第一权重是renderQueue,第二权重是sortingOrder,最后是Z。所以只要让sortingOrder保持为0,就是纯粹的Z排了。
虽然Canvas并没有继承自Renderer,但是在渲染管线里同样是被当做Renderer处理的。当选中Override Sorting,SortingOrder和其他物体一样固定为0的时候,就成为了和其他Renderer完全一样的东西。
【UGUI】將Particle夾在UI中間(会增加DrawCall)
二、UIParticle

在unity官方论坛看到的一个解决方案,可以将Particle直接转换成CanvasRenderer元素显示。下面学习一下这种解决方案的源码
在Update里禁用了默认ParticleSystemRenderer的渲染,然后每帧触发ui重建,从ParticleSystem拿到生成的粒子对象,然后遍历所有粒子对象,去计算粒子的UV,生成mesh,计算UV的细节表示看不懂,textureSheetAnimationModule也表示没懂。
  1.                 protected virtual void Update ()
  2.                 {
  3.                         if (!m_IgnoreTimescale)
  4.                         {
  5.                                 if (ParticleSystem != null && ParticleSystem.isPlaying)
  6.                                 {
  7.                                         SetVerticesDirty();
  8.                                 }
  9.                         }
  10.                         else
  11.                         {
  12.                                 if (ParticleSystem != null)
  13.                                 {
  14.                                         ParticleSystem.Simulate(Time.unscaledDeltaTime, true, false);
  15.                                         SetVerticesDirty();
  16.                                 }
  17.                         }
  18.                         // disable default particle renderer, we using our custom
  19.                         if (m_ParticleSystemRenderer != null && m_ParticleSystemRenderer.enabled)
  20.                                 m_ParticleSystemRenderer.enabled = false;
  21.                 }
复制代码
  1. //UI重建
  2.                 protected override void OnPopulateMesh (VertexHelper toFill)
  3.                 {
  4.                         Profiler.BeginSample("UIParticles OnPopulateMesh");
  5.                         if (ParticleSystem == null) {
  6.                                 base.OnPopulateMesh (toFill);
  7.                                 return;
  8.                         }
  9.                         GenerateParticlesBillboards (toFill);
  10.                         Profiler.EndSample();
  11.                 }
  12.                 private void GenerateParticlesBillboards (VertexHelper vh)
  13.                 {
  14.                         //read modules ones, cause they produce allocations when read.
  15.                         var mainModule = ParticleSystem.main;
  16.                        
  17.                         var textureSheetAnimationModule = ParticleSystem.textureSheetAnimation;
  18.                        
  19.                         InitParticlesBuffer (mainModule);
  20.                         // 从ParticleSystem拿到生成的粒子对象
  21.                         <span class="kt">int numParticlesAlive = ParticleSystem.GetParticles (m_Particles);
  22.                        
  23.                         vh.Clear ();
  24.                        
  25.                         var isWorldSimulationSpace = mainModule.simulationSpace == ParticleSystemSimulationSpace.World;
  26.                         if (RenderMode == UiParticleRenderMode.Mesh)
  27.                         {
  28.                                 if (RenderedMesh != null)
  29.                                 {
  30.                                         InitMeshData();
  31.                                         for (int i = 0; i < numParticlesAlive; i++)
  32.                                         {
  33.                                                 DrawParticleMesh(m_Particles[i], vh, frameOverTime, isWorldSimulationSpace,
  34.                                                         textureSheetAnimationModule, m_MeshVerts, m_MeshTriangles, m_MeshUvs);
  35.                                         }
  36.                                 }
  37.                         }
  38.                         else
  39.                         {
  40.                                 for (int i = 0; i < numParticlesAlive; i++)
  41.                                 {
  42.                                         DrawParticleBillboard (m_Particles [i], vh, frameOverTime,
  43.                                                 velocityOverTimeX, velocityOverTimeY, velocityOverTimeZ, isWorldSimulationSpace,
  44.                                                 textureSheetAnimationModule);
  45.                                 }
  46.                         }
  47.                 }
复制代码
具体:工具源码

参考

UGUI研究院之不添加摄像机解决UI与UI特效叠层问题(九)
flashyiyi:UGUI和特效模型混排的解决方案
粒子渲染模組
粒子系統基礎

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-9-20 10:44 , Processed in 0.105699 second(s), 26 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表