zoukankan      html  css  js  c++  java
  • Unity中的粒子特效的 RendererQ 排序

    这里接https://www.cnblogs.com/luguoshuai/p/10021660.html

    这里介绍两套粒子排序的方法。

    首先声明,这两套排序方法均不是本人所写,是在项目开发的过程当中,看到同事的设计,然后我就记录了下来了,作为后续的学习与使用。

    方法一:

     1 using System.Collections.Generic;
     2 using UnityEngine;
     3 
     4 public class UIRenderQueueSorter : MonoBehaviour
     5 {
     6     [SerializeField]
     7     UIWidget m_source;  //基础RendererQ,粒子的 RendererQ 均是在此基础上递增的
     8     [SerializeField]
     9     int m_offset;       //每次递增的幅度
    10     [SerializeField]
    11     List<Renderer> m_renderers = new List<Renderer>();
    12 
    13     public void Initialize()
    14     {
    15         Renderer[] renders = transform.GetComponentsInChildren<Renderer>(true);
    16         m_renderers.AddRange(renders);
    17     }
    18 
    19     void Update()
    20     {
    21         if (m_source && m_renderers.Count > 0)
    22         {
    23             for (int i = 0; i < m_renderers.Count; i++)
    24             {
    25                 Renderer r = m_renderers[i];
    26                 if (r && r.sharedMaterial && m_source.drawCall != null)
    27                     r.sharedMaterial.renderQueue = m_source.drawCall.renderQueue + m_offset;
    28             }
    29         }
    30     }
    31 
    32     public void AddRenderer(Renderer r)
    33     {
    34         if (!m_renderers.Contains(r))
    35         {
    36             m_renderers.Add(r);
    37         }
    38     }
    39 
    40     public void ClearAllRenderers()
    41     {
    42         m_renderers.Clear();
    43     }
    44 
    45     public UIWidget Source
    46     {
    47         set { m_source = value; }
    48     }
    49 
    50     public int Offset
    51     {
    52         set { m_offset = value; }
    53     }
    54 }

    用法介绍,将该脚本挂载到粒子特效的父级对象上,使用的时候,只需要调用一下Initialize()方法即可。

    方法二:

    这个其实是对NGUI的一个简答扩展,粒子的 RendererQ 是以Panel为单位来计算的

    对NGUI的修改,添加如下变量:

    1     public List<UIParticlesEffectAutoSort> uiEffectList = new List<UIParticlesEffectAutoSort>();

    修改NGUI的 LateUpdate 方法为如下:

     1 void LateUpdate ()
     2     {
     3 #if UNITY_EDITOR
     4         if (mUpdateFrame != Time.frameCount || !Application.isPlaying)
     5 #else
     6         if (mUpdateFrame != Time.frameCount)
     7 #endif
     8         {
     9             mUpdateFrame = Time.frameCount;
    10 
    11             // Update each panel in order
    12             for (int i = 0, imax = list.Count; i < imax; ++i)
    13                 list[i].UpdateSelf();
    14 
    15             int rq = 3000;
    16             int addRq = 0;
    17 
    18             // Update all draw calls, making them draw in the right order
    19             for (int i = 0, imax = list.Count; i < imax; ++i)
    20             {
    21                 UIPanel p = list[i];
    22 
    23                 if (p.renderQueue == RenderQueue.Automatic)
    24                 {
    25                     p.startingRenderQueue = rq;
    26                     p.UpdateDrawCalls();
    27                     rq += p.drawCalls.Count;
    28                     addRq = 0;
    29                     for(int j = 0; j < p.uiEffectList.Count; ++j)
    30                     {
    31                         addRq = Mathf.Max(addRq, p.uiEffectList[j].UpdateRendererQueue(rq));
    32                     }
    33                     rq += addRq;
    34                 }
    35                 else if (p.renderQueue == RenderQueue.StartAt)
    36                 {
    37                     p.UpdateDrawCalls();
    38                     if (p.drawCalls.Count != 0)
    39                         rq = Mathf.Max(rq, p.startingRenderQueue + p.drawCalls.Count);
    40                 }
    41                 else // Explicit
    42                 {
    43                     p.UpdateDrawCalls();
    44                     if (p.drawCalls.Count != 0)
    45                         rq = Mathf.Max(rq, p.startingRenderQueue + 1);
    46                 }
    47             }
    48         }
    49     }

    UIParticlesEffectAutoSort:

     1 using UnityEngine;
     2 using System.Collections.Generic;
     3 
     4 public class UIParticlesEffectAutoSort : MonoBehaviour
     5 {
     6     protected UIPanel panel;
     7     protected List<Material> mats = new List<Material>();
     8     int beginRenderQ = -1, totalRenderQ = 0;
     9     void Start()
    10     {
    11         panel = gameObject.GetComponentInParent<UIPanel>();
    12         if (panel == null)
    13         {
    14             enabled = false;
    15         }
    16         else
    17         {
    18             Renderer[] rds = gameObject.GetComponentsInChildren<Renderer>(true);
    19             for (int i = 0; i < rds.Length; ++i)
    20             {
    21                 for (int j = 0; j < rds[i].sharedMaterials.Length; ++j)
    22                 {
    23                     if (rds[i].sharedMaterials[j] != null)
    24                         mats.Add(rds[i].sharedMaterials[j]);
    25                 }
    26             }
    27             mats.Sort(delegate(Material a, Material b)
    28             {
    29                 return a.renderQueue.CompareTo(b.renderQueue);
    30             });
    31             panel.uiEffectList.Add(this);
    32         }
    33     }
    34     void OnDestroy()
    35     {
    36         if (panel != null)
    37             panel.uiEffectList.Remove(this);
    38     }
    39     public int UpdateRendererQueue(int rq)
    40     {
    41         if (panel == null)
    42             return 0;
    43         if (mats.Count > 0)
    44         {
    45             if (beginRenderQ != rq)
    46             {
    47                 beginRenderQ = rq;
    48                 int tempRenderQ = -1, addRenderQ = 0;
    49                 for (int i = 0; i < mats.Count; ++i)
    50                 {
    51                     if (mats[i] == null)
    52                         continue;
    53                     if (tempRenderQ != mats[i].renderQueue)
    54                     {
    55                         tempRenderQ = mats[i].renderQueue;
    56                         ++addRenderQ;
    57                     }
    58                     mats[i].renderQueue = beginRenderQ + addRenderQ;
    59                 }
    60                 totalRenderQ = addRenderQ + 1;
    61             }
    62             return totalRenderQ;
    63         }
    64         return 0;
    65     }
    66 }

    用法:将该脚本挂载到粒子特效的父级对象上即可。

    需要注意的是,这两个方法都是调整的 sharedMaterials,如果在使用的过程中发现粒子的层级不正确,试着调整materials即可。

    比如,方法二:

     1 using System.Collections.Generic;
     2 using UnityEngine;
     3 
     4 public class UISelfParticalEffectAutoSort : UIParticlesEffectAutoSort
     5 {
     6     void Start()
     7     {
     8         panel = gameObject.GetComponentInParent<UIPanel>();
     9         if (panel == null)
    10         {
    11             enabled = false;
    12         }
    13         else
    14         {
    15             Renderer[] rds = gameObject.GetComponentsInChildren<Renderer>(true);
    16             for (int i = 0; i < rds.Length; ++i)
    17             {
    18                 for (int j = 0, jMax = rds[i].materials.Length; j < jMax; ++j)
    19                 {
    20                     if (rds[i].materials[j] != null)
    21                         mats.Add(rds[i].materials[j]);
    22                 }
    23             }
    24             mats.Sort(delegate(Material a, Material b)
    25             {
    26                 return a.renderQueue.CompareTo(b.renderQueue);
    27             });
    28             panel.uiEffectList.Add(this);
    29         }
    30     }
    31     void OnDestroy()
    32     {
    33         if (panel != null)
    34             panel.uiEffectList.Remove(this);
    35         for (int i = mats.Count - 1; i >= 0; --i)
    36             GameObject.Destroy(mats[i]);
    37         mats.Clear();
    38     }
    39 }

    主要看Start方法。

  • 相关阅读:
    Codeforces Round #388 (Div. 2)
    Codeforces Round #388 (Div. 2)
    Codeforces Round #388 (Div. 2)
    FZU 1914 单调队列
    ACM学习历程—POJ 3764 The xor-longest Path(xor && 字典树 && 贪心)
    ACM学习历程—SGU 275 To xor or not to xor(xor高斯消元)
    ACM学习历程—CSU 1216 异或最大值(xor && 贪心 && 字典树)
    ACM学习历程—HDU 5512 Pagodas(数学)
    ACM学习历程—HDU5521 Meeting(图论)
    ACM学习历程—HDU1030 Delta-wave(数学)
  • 原文地址:https://www.cnblogs.com/luguoshuai/p/10021833.html
Copyright © 2011-2022 走看看