井底燕雀傥 发表于 2021-1-7 09:21

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

前言

游戏开发过程中,肯定有特效的存在,一旦在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也表示没懂。
                protected virtual void Update ()
                {
                        if (!m_IgnoreTimescale)
                        {
                                if (ParticleSystem != null && ParticleSystem.isPlaying)
                                {
                                        SetVerticesDirty();
                                }
                        }
                        else
                        {
                                if (ParticleSystem != null)
                                {
                                        ParticleSystem.Simulate(Time.unscaledDeltaTime, true, false);
                                        SetVerticesDirty();
                                }
                        }

                        // disable default particle renderer, we using our custom
                        if (m_ParticleSystemRenderer != null && m_ParticleSystemRenderer.enabled)
                                m_ParticleSystemRenderer.enabled = false;
                }

//UI重建
                protected override void OnPopulateMesh (VertexHelper toFill)
                {
                        Profiler.BeginSample("UIParticles OnPopulateMesh");
                        if (ParticleSystem == null) {
                                base.OnPopulateMesh (toFill);
                                return;
                        }
                        GenerateParticlesBillboards (toFill);
                        Profiler.EndSample();
                }

                private void GenerateParticlesBillboards (VertexHelper vh)
                {
                        //read modules ones, cause they produce allocations when read.
                        var mainModule = ParticleSystem.main;
                       
                        var textureSheetAnimationModule = ParticleSystem.textureSheetAnimation;
                       
                        InitParticlesBuffer (mainModule);
                        // 从ParticleSystem拿到生成的粒子对象
                        <span class="kt">int numParticlesAlive = ParticleSystem.GetParticles (m_Particles);
                       
                        vh.Clear ();
                       
                        var isWorldSimulationSpace = mainModule.simulationSpace == ParticleSystemSimulationSpace.World;

                        if (RenderMode == UiParticleRenderMode.Mesh)
                        {
                                if (RenderedMesh != null)
                                {
                                        InitMeshData();
                                        for (int i = 0; i < numParticlesAlive; i++)
                                        {
                                                DrawParticleMesh(m_Particles, vh, frameOverTime, isWorldSimulationSpace,
                                                        textureSheetAnimationModule, m_MeshVerts, m_MeshTriangles, m_MeshUvs);
                                        }
                                }
                        }
                        else
                        {
                                for (int i = 0; i < numParticlesAlive; i++)
                                {
                                        DrawParticleBillboard (m_Particles , vh, frameOverTime,
                                                velocityOverTimeX, velocityOverTimeY, velocityOverTimeZ, isWorldSimulationSpace,
                                                textureSheetAnimationModule);
                                }
                        }
                }具体:工具源码

参考

UGUI研究院之不添加摄像机解决UI与UI特效叠层问题(九)
flashyiyi:UGUI和特效模型混排的解决方案
粒子渲染模組
粒子系統基礎
页: [1]
查看完整版本: 【unity游戏开发】UI粒子特效遮挡问题解决