zoukankan      html  css  js  c++  java
  • NGUI处理特效显示和面板显示夹层问题

    NGUI相当不错,但是有一点比较纠结的就是面板上显示特效的时候,你会发现要么盖住特效,要么面板永远无法盖住特效。很多人说改renderqueue,然后就能显示了,然后下面一堆楼主给力。。。。呵呵。 
           
    先从原理上解释吧,NGUI是通过调整renderqueue来显示不同层,然后它的shader是不写入z值的,然后特效刚好也是不写入z值的,所以你 
    要控制特效和UI的关系,确实只能通过renderqueue.但是如果你只是单纯让renderqueue非常大,那么特效就会永远在面板之上。 
          如果你想要两个面板夹住特效,那么就需要看NGUI源代码了。 
          这里希望大家自己去看一下,我直接贴上修改方案: 
    if (this.widgetInFrontOfMe != null && this.widgetInFrontOfMe.drawCall != null) { 
                 int rq = this.widgetInFrontOfMe.drawCall.renderQueue + 1; 
                 Debug.Log(rq); 
                 foreach (Material material in m_renderer.materials) { 
                     if(material.renderQueue != rq) 
                     { 
                         material.renderQueue = rq; 
                     } 
                 } 
             } 


    首先这段代码就是将特效的renderqueu调整成你想要放置的物体的前面。然后你如果在Update()或者LateUpdate()中执行这 
    段代码,你会发现它工作的不错,就是偶尔会闪一下,这是因为这段代码先更新了,然后NGUI才更新,所以导致滞后一帧。对于我这种完美主义者来说,这是不 
    能接受的。所以我修改了UIPanel的源代码,然里面全部更新完毕后,再去调用这个函数。哈哈,一切都非常完美。 
    完整代码如下:using UnityEngine; 
     using System.Collections.Generic; 
      
     public class UISortBehavior : MonoBehaviour 
     { 
         public UIPanel panel; 
         public UIWidget widgetInFrontOfMe; 
         public bool AddQueue=true; 
         
         [System.NonSerialized] 
         Renderer m_renderer; 
         
         void Awake() { 
             m_renderer = this.renderer; 
         } 
      
         public void initPanel(UIPanel p) 
         { 
             panel = p; 
         } 
      
         void Start() 
         { 
             panel.addUISort (this); 
         } 
      
         public void UpdateSortUI() 
         { 
             if (this.widgetInFrontOfMe != null && this.widgetInFrontOfMe.drawCall != null) { 
                 int rq = this.widgetInFrontOfMe.drawCall.renderQueue + 1; 
                 if(!AddQueue) 
                     rq -= 2; 
                 foreach (Material material in m_renderer.materials) { 
                     if(material.renderQueue != rq) 
                     { 
                         material.renderQueue = rq; 
                     } 
                 } 
             } 
         } 
      
         void OnDestroy() 
         { 
             if(panel != null) 
                 panel.removeUISort (this); 
         } 
      



    当然UIPanel中也要修改: 
    void LateUpdate () 
         { 
             if (mUpdateFrame != Time.frameCount) 
             { 
                 mUpdateFrame = Time.frameCount; 
      
                 // Update each panel in order 
                 for (int i = 0; i < list.size; ++i) 
                     list.UpdateSelf(); 
      
                 int rq = 3000; 
      
                 // Update all draw calls, making them draw in the right order 
                 for (int i = 0; i < list.size; ++i) 
                 { 
                     UIPanel p = list.buffer
      
                     if (p.renderQueue == RenderQueue.Automatic) 
                     { 
                         p.startingRenderQueue = rq; 
                         p.UpdateDrawCalls(); 
                         //rq += p.drawCalls.size; 
                         rq += p.drawCalls.size * 2; 
                     } 
                     else if (p.renderQueue == RenderQueue.StartAt) 
                     { 
                         p.UpdateDrawCalls(); 
                         if (p.drawCalls.size != 0) 
                             rq = Mathf.Max(rq, p.startingRenderQueue + p.drawCalls.size * 2); 
                             //rq = Mathf.Max(rq, p.startingRenderQueue + p.drawCalls.size); 
                     } 
                     else // Explicit 
                     { 
                         p.UpdateDrawCalls(); 
                         if (p.drawCalls.size != 0) 
                             rq = Mathf.Max(rq, p.startingRenderQueue + 2); 
                             //rq = Mathf.Max(rq, p.startingRenderQueue + 1); 
                     } 
                     p.updateUISort(); 
                 } 
      
      
             } 
         } 
      
    List<UISortBehavior> container = new List<UISortBehavior>(); 
      
         public void addUISort(UISortBehavior uiSort) 
         { 
             if(container.Contains(uiSort)) 
             { 
                 return; 
             } 
             container.Add (uiSort); 
         } 
      
         public void removeUISort(UISortBehavior uiSort) 
         { 
             container.Remove (uiSort); 
         } 
      
         public void updateUISort() 
         { 
             for(int i = 0; i < container.Count; i++) 
             { 
                 container.UpdateSortUI(); 
             } 
         } 

    void UpdateDrawCalls () 
         { 
             Transform trans = cachedTransform; 
             bool isUI = usedForUI; 
      
             if (clipping != UIDrawCall.Clipping.None) 
             { 
                 drawCallClipRange = finalClipRegion; 
                 drawCallClipRange.z *= 0.5f; 
                 drawCallClipRange.w *= 0.5f; 
             } 
             else drawCallClipRange = Vector4.zero; 
      
             // Legacy functionality 
             if (drawCallClipRange.z == 0f) drawCallClipRange.z = Screen.width * 0.5f; 
             if (drawCallClipRange.w == 0f) drawCallClipRange.w = Screen.height * 0.5f; 
      
             // DirectX 9 half-pixel offset 
             if (halfPixelOffset) 
             { 
                 drawCallClipRange.x -= 0.5f; 
                 drawCallClipRange.y += 0.5f; 
             } 
      
             Vector3 pos; 
      
             // We want the position to always be on even pixels so that the 
             // panel's contents always appear pixel-perfect. 
             if (isUI) 
             { 
                 Transform parent = cachedTransform.parent; 
                 pos = cachedTransform.localPosition; 
      
                 if (parent != null) 
                 { 
                     float x = Mathf.Round(pos.x); 
                     float y = Mathf.Round(pos.y); 
      
                     drawCallClipRange.x += pos.x - x; 
                     drawCallClipRange.y += pos.y - y; 
      
                     pos.x = x; 
                     pos.y = y; 
                     pos = parent.TransformPoint(pos); 
                 } 
                 pos += drawCallOffset; 
             } 
             else pos = trans.position; 
      
             Quaternion rot = trans.rotation; 
             Vector3 scale = trans.lossyScale; 
      
             for (int i = 0; i < drawCalls.size; ++i) 
             { 
                 UIDrawCall dc = drawCalls.buffer
      
                 Transform t = dc.cachedTransform; 
                 t.position = pos; 
                 t.rotation = rot; 
                 t.localScale = scale; 
      
                 //dc.renderQueue = (renderQueue == RenderQueue.Explicit) ? startingRenderQueue : startingRenderQueue + i; 
                 dc.renderQueue = (renderQueue == RenderQueue.Explicit) ? startingRenderQueue : startingRenderQueue + i * 2; 
                 dc.alwaysOnScreen = alwaysOnScreen && 
                     (mClipping == UIDrawCall.Clipping.None || mClipping == UIDrawCall.Clipping.ConstrainButDontClip); 
     #if !UNITY_3_5 && !UNITY_4_0 && !UNITY_4_1 && !UNITY_4_2 
                 dc.sortingOrder = mSortingOrder; 
     #endif 
             } 
         }

  • 相关阅读:
    (二)、一步一步学GTK+之窗口
    phpcms v9 评论的bug.
    为discuz x2.5添加播放附件(mp4)的方法
    code::blocks + C + lua 编译环境
    C语言从声卡录音的一个demo
    泛型集合(.NET 2.0)
    VS2008对ASP.NET引用的外部JS文件不能调试
    for循环和foreach
    CSS之DIV上下左右居中
    GridView控件相关(来自互联网)
  • 原文地址:https://www.cnblogs.com/AlanCheng/p/5531988.html
Copyright © 2011-2022 走看看