美文网首页
UGUI工具——获取Canvas网格重建的UI元素

UGUI工具——获取Canvas网格重建的UI元素

作者: 莫忘初心_倒霉熊 | 来源:发表于2021-05-30 15:37 被阅读0次

    当Canvas需要重绘UI时,Unity内部会调用Canvas.SendWillRenderCanvas,进行网格重建,但是我们不知道是由于哪个UI元素引起了哪个Canvas的网格重建。
    通过查看UGUI源码,我们发现所有待重建的UI元素都被保存在CanvasUpdateRegistry.cs类中。

    private readonly IndexedSet<ICanvasElement> m_LayoutRebuildQueue = new IndexedSet<ICanvasElement>();
    private readonly IndexedSet<ICanvasElement> m_GraphicRebuildQueue = new IndexedSet<ICanvasElement>();
    

    因此,我们可以通过反射的方式,获取这俩个列表中的数据。代码如下:

    using System.Collections.Generic;
    using System.Reflection;
    using UnityEngine;
    using UnityEngine.UI;
    using Object = UnityEngine.Object;
    
    public class UGUIUtil : MonoBehaviour
    {
        private IList<ICanvasElement> m_LayoutRebuildQueue;
        private IList<ICanvasElement> m_GraphicRebuildQueue;
    
        private void Awake()
        {
            System.Type type = typeof(CanvasUpdateRegistry);
            FieldInfo field = type.GetField("m_LayoutRebuildQueue", BindingFlags.NonPublic | BindingFlags.Instance);
            m_LayoutRebuildQueue = (IList<ICanvasElement>) field.GetValue(CanvasUpdateRegistry.instance);
            field = type.GetField("m_GraphicRebuildQueue", BindingFlags.NonPublic | BindingFlags.Instance);
            m_GraphicRebuildQueue = (IList<ICanvasElement>) field.GetValue(CanvasUpdateRegistry.instance);
        }
    
        private void Update()
        {
            for (int j = 0; j < m_LayoutRebuildQueue.Count; j++)
            {
                var rebuild = m_LayoutRebuildQueue[j];
                if (ObjectValidFofUpdate(rebuild))
                {
                    Debug.LogFormat("m_LayoutRebuildQueue中{0}引起{1}网格重建", rebuild.transform.name, 
    rebuild.transform.GetComponent<Graphic>().canvas.name);
                }
            }
    
            for (int j = 0; j < m_GraphicRebuildQueue.Count; j++)
            {
                var element = m_GraphicRebuildQueue[j];
                if (ObjectValidFofUpdate(element))
                {
                    Debug.LogFormat("m_GraphicRebuildQueue中{0}引起{1}网格重建",element.transform.name,
    element.transform.GetComponent<Graphic>().canvas.name);
                }
            }
        }
    
        private bool ObjectValidFofUpdate(ICanvasElement element)
        {
            var valid = element != null;
            var isUnityObject = element is Object;
            if (isUnityObject)
                valid = (element as Object) != null;
            return valid;
        }
    }
    

    相关文章

      网友评论

          本文标题:UGUI工具——获取Canvas网格重建的UI元素

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