美文网首页unity
UGUI及NGUI实现粒子夹层渲染

UGUI及NGUI实现粒子夹层渲染

作者: Levi_Wan | 来源:发表于2017-02-23 22:52 被阅读1112次

    我们在开发中,经常会遇见粒子,Mesh,Spine等在渲染的时候会被UI层给挡住从而无法达到理想的体验效果。现在我们来解决这些问题并实现夹层效果:

    UGUI:

    效果图:

    Paste_Image.png

    我们可以看见粒子渲染在Pink的Image之上而在Green的Image下。实现了夹层效果。

    技术实现
      核心:通过脚本修改Canvas中的Order in layer。

    • 首先我们需要修改Canvas的渲染模式。
      • 在Unity中通过渲染队列来进行渲染的先后排序,从小到大分别为:
    • Background
    • Geometry(Opaque)
    • Alpha Test
    • Transparent
    • Overlay。
    • 我们修改Canvas的渲染模式为:Screen Space - Camera,并将我们的主摄像机赋予它。
    Paste_Image.png
    • 接着我们编写脚本来更改需要修改Order的Sprite(Image)UIDepth。

        using UnityEngine;  
        using System.Collections;  
        using UnityEngine.UI;  
      
        public class UIDepth : MonoBehaviour {  
        public int order;  
        public bool isUI = true;  
        void Start () {  
            if(isUI) {  
                Canvas canvas = GetComponent<Canvas>();  
                if( canvas == null){  
                    canvas = gameObject.AddComponent<Canvas>();  
                }  
                canvas.overrideSorting = true;  
                canvas.sortingOrder = order;  
            } else {  
                Renderer []renders  =  GetComponentsInChildren<Renderer>    ();  
              
                foreach(Renderer render in renders){  
                    render.sortingOrder = order;  
                }  
            }  
         }  
        }
      
    • 将这么脚本赋予需要修改Order的Image。并修改Order。

    Paste_Image.png
    • 最后修改粒子的Renerer,Canvas中默认的Order为0,我们修改了一个Image的Order为2,此时我们将粒子的Order修改为1.实现夹层。
    Paste_Image.png
    NGUI:

    NGUI也是基于MVC架构开发的插件。

    • Model:UIGeometry。
    • View: UIWidget。
    • Control: UICamera。
    Paste_Image.png

    三种解决方案:

    • 修改NGUI中的UIPanel脚本中的默认的RenderQueue, 调整到3000以下,这样就不会遮挡住粒子特效了。
    • 使用另外的一个摄像机来渲染粒子特效,缺点是UI窗口切换时,不易控制。
    • 更改粒子特效的Shader中的RendererQueue值。

    NGUI在渲染时,UIWidget会在LateUpdate中调用NGUI的UIDrawCall来完成渲染,我们可以通过自写代码,将我们需要渲染的Mesh,粒子等加入NGUI的Renderer Queue就能完成最完善的夹层渲染解决方案。(最佳方案)

    • 这里介绍更改Renderer Queue的方法。

    • 我们通过一个RenderQueueModifier 类来进行UIDrawCall的Renderer Queue顺序进行更改,让添加这个物体的对象参与渲染(在两个UIDrawCall中插入自己的Renderer Queue来实现夹层的层级排序)。


      Paste_Image.png
    • Target参数为:在谁的上层进行渲染。

     using UnityEngine;
     using System.Collections;
     
     public class RenderQueueModifier : MonoBehaviour {
    
    
    public UIPanel m_panel;
    public UIWidget m_target;
    public bool isForSpine = true;
    
    
    
    public Renderer renderer;
    void Awake() {
    
            renderer = GetComponent<Renderer>();
    
    }
    
    
    void OnEnable() {
        AddToPanel();
    }
    public void Set(UIPanel m_panel, UIWidget m_target, bool isForSpine) 
    {
        this.m_panel = m_panel;
        this.m_target = m_target;
        this.isForSpine = isForSpine;
        AddToPanel();
    }
    
    void AddToPanel() {
        if (m_panel != null) m_panel.renderQueueModifiers.Add(this);
    }
    
    void OnDisable() {
        
        m_panel.renderQueueModifiers.Remove(this);
    }
    
    
    
    
    
    int lasetQueue = int.MinValue;
    
    
    public void setQueue(int queue)
    {
        if (this.lasetQueue != queue) {
            this.lasetQueue = queue;
    
                renderer.material.renderQueue = this.lasetQueue;
        }
    }
     }
    
    • 接着进行UIPanel的代码更改。

    • 自己插入的Renderer Queue,参与DrawCall的渲染。


      Paste_Image.png
    • 通过查找之前引用的Target的UIDrawCall,为我们将要插入的DrawCall留出空当。(将Mesh和粒子的渲染层级跟NGUI统一起来)


      Paste_Image.png
    • 通过查找之前引用的Target的UIDrawCall,我们将我们的DC插入在Target的层级之上。


      Paste_Image.png
    • 我们程序有多少个UIDrawCall进行刷新我们就通过刷新的时候让我们的自写的UIDrawCall也参与刷新显示。


      Paste_Image.png

    相关文章

      网友评论

        本文标题:UGUI及NGUI实现粒子夹层渲染

        本文链接:https://www.haomeiwen.com/subject/kkqiwttx.html