美文网首页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