zoukankan      html  css  js  c++  java
  • UGUI 粒子特效与UI层级问题

    游戏中,界面上有些按钮之上需要放置一个特效,或者有些区域显示比如image上显示一个特效,这时候如果再打开一个UI,我们需要让新的UI显示在特效上层,而不是被特效遮挡,这是就需要设置特效的渲染顺序。

    设置特效的order in layer,新版的unity中,particle system可以直接设置render的order,但是特效中有些是使用particle system做的,有些又是直接用的图像动画等等,而类似MeshRender的order in layer是不能在编辑器直接设置的,

    所以靠手工设置是不现实的,需要用脚本设置。

    代码:

    // 深度遍历设置所有 Render 的 SortingLayer
            public static void setRenderSortingLayerByActor(GameObject actor, int order, bool isRecursion)
            {
                if (null != actor)
                {
                    UtilApi.setSpriteRenderSortingLayerByActor(actor, order);
                    UtilApi.setParticleSystemSortingLayerByActor(actor, order);
                    UtilApi.setMeshRenderSortingLayerByActor(actor, order);
    
                    int childCount = actor.transform.childCount;
                    int idx = 0;
                    Transform childTrans = null;
    
                    if (isRecursion)
                    {
                        for (idx = 0; idx < childCount; ++idx)
                        {
                            childTrans = actor.transform.GetChild(idx);
                            UtilApi.setRenderSortingLayerByActor(childTrans.gameObject, order, isRecursion);
                        }
                    }
                }
            }
    
    static public void setSpriteRenderSortingLayerByActor(UnityEngine.GameObject actor, int order)
            {
                if (null != actor)
                {
                    SpriteRenderer render = null;
                    render = actor.GetComponent<SpriteRenderer>();
    
                    UtilApi.setSpriteRenderSortingLayerBySpriteRenderer(render, order);
                }
            }
    
    /**
             * @brief  unity渲染层级关系小结
             * @ref http://blog.csdn.net/meegomeego/article/details/42060389
             */
            // 可以在编辑器中设置
            static public void setSpriteRenderSortingLayerBySpriteRenderer(SpriteRenderer render, int order)
            {
                if (null != render && render.sortingOrder != order)
                {
                    render.sortingOrder = order;
                }
            }
    
    static public void setParticleSystemSortingLayerByActor(UnityEngine.GameObject actor, int order)
            {
                if (null != actor)
                {
                    ParticleSystem particleSystem = null;
                    particleSystem = actor.GetComponent<ParticleSystem>();
    
                    UtilApi.setParticleSystemSortingLayer(particleSystem, order);
                }
            }
    
    // 不能在编辑器中设置
            static public void setParticleSystemSortingLayer(ParticleSystem particleSystem, int order)
            {
                if (null != particleSystem)
                {
                    Renderer render = particleSystem.GetComponent<Renderer>();
                    if (null != render && render.sortingOrder != order)
                    {
                        render.sortingOrder = order;
                    }
                }
            }
    
    static public void setMeshRenderSortingLayerByActor(UnityEngine.GameObject actor, int order)
            {
                if (null != actor)
                {
                    UnityEngine.MeshRenderer meshRenderer = null;
                    meshRenderer = actor.GetComponent<UnityEngine.MeshRenderer>();
    
                    UtilApi.setMeshRenderSortingLayer(meshRenderer, order);
                }
            }
    
    // 不能在编辑器中设置
            static public void setMeshRenderSortingLayer(UnityEngine.MeshRenderer meshRenderer, int order)
            {
                if (null != meshRenderer && meshRenderer.sortingOrder != order)
                {
                    meshRenderer.sortingOrder = order;
                }
            }
    View Code

    使用时:UtilApi.setRenderSortingLayerByActor(this.mSelfGo, 1, true);   参数中,this.mSelfGo就是特效实例化的父节点,1就是设置的order in layer,因为ui的order默认都是0,所以这个设为1,true循环设置子节点

    按理说这个order in layer设置为0我觉得应该也是正确的,但在我的游戏中设置为0就无法显示特效,我确实没有理解。

    我的游戏结点如图:

    ef_quan2all就是我的特效实例,按照这个顺序应该也是最后渲染的,不明白设置为0为何就不显示,不知有人能否告知。

    order in layer设为1后,特效显示了,但是后面出现了一个问题,如果这时打开一个其他的UI,特效会遮挡这个UI,坑爹。。

    这时就要使出杀手锏了,因为UI上类似Image或者Button是无法设置order in layer的,所以要给这个被遮挡的UI添加一个Canvas,Canvas可以设置order,那么将其设置为2,比特效的大,不错,可以显示了,但是又出现一个问题,这个界面上的按钮事件被拦截了,擦。。。

    又一招出手,给其再设置一个Graphic Raycster,参数如下

    终于完美了。。,既可以显示特效,还不会遮挡UI

    至此有个问题,如果界面很多都需要设置上述的canvas,那就需要自己实现一个管理类,给每个ui设置它的order,不过canvas会影响合并批次,所以不能有太多,自己权衡。

  • 相关阅读:
    MFC学习之程序执行过程梳理
    二分法插入排序
    内存泄漏以及常见的解决方法
    Ant命令行操作
    Android Intent的几种使用方法全面总结
    YII 页面缓存
    JAVA修饰符类型(public,protected,private,friendly)
    unity3d插件Daikon Forge GUI 中文教程-5-高级控件listbox和progress bar的使用
    ostringstream的使用方法
    程序猿接私活经验总结,来自csdn论坛语录
  • 原文地址:https://www.cnblogs.com/lan-yt/p/7810586.html
Copyright © 2011-2022 走看看