UGUI 显隐效率问题

好早以前就在网上看到过对于UI的显示和隐藏最好使用CanvasGroup组件来控制会比较好,一直没有做过测试,这次来补下坑,顺便学了点性能分析Profiler工具。

  • 首先创建一个BasePanel脚本,通过CanvasGroup组件来实现UI面板的显示(OnEnter)和隐藏(OnExit)。这里的BasePanel相当于是UIPanel的基类了,这里我只是抽出了一部分,等以后有空了把简易的UI管理类也一起讲了
[RequireComponent(typeof(CanvasGroup))]
public class BasePanel : MonoBehaviour
{
    private CanvasGroup m_CanvasGroup;

    private void Awake()
    {
        m_CanvasGroup = GetComponent<CanvasGroup>();
    }

    public void OnEnter()
    {
        m_CanvasGroup.alpha = 1;
        m_CanvasGroup.blocksRaycasts = true;
    }

    public void OnExit()
    {
        m_CanvasGroup.alpha = 0;
        m_CanvasGroup.blocksRaycasts = false;
    }
}
  • 然后就创建一个测试脚本,用于比较CanvasGroup组件和使用SetAcive(true/false)的性能消耗。这边要引入命名空间UnityEngine.Profiling才可以使用性能检测,在需要性能测试的函数前后添加Profiler.BeginSample(“展示的名字”)和Profiler.EndSample()即可。这里为了明显展现性能消耗,开放了一个num变量来控制我们循环次数。
public class Main : MonoBehaviour
{
    public BasePanel panel;
    public int num;
    //public GameObject panelGo;

    private void Awake()
    {
        //panel = panelGo.GetComponent<BasePanel>();
    }

    private void Update()
    {
        Profiler.BeginSample("CanvasGroup");
        CanvasGroupFun();
        Profiler.EndSample();

        Profiler.BeginSample("SetActive");
        ActiveFun();
        Profiler.EndSample();
    }

    void CanvasGroupFun()
    {
        for (int i = 0; i < num; i++)
        {
            panel.OnEnter();
            panel.OnExit();
        }
    }

    void ActiveFun()
    {
        for (int i = 0; i < num; i++)
        {
            panel.gameObject.SetActive(true);
            panel.gameObject.SetActive(false);
        }
        
    }
}

将num设为100次结果如图:


与消除panel.gameObject进行对比 无多大区别

public class GameTest : MonoBehaviour
{
    public BasePanel panel;
    public int num;
    public GameObject panelGo;

    private void Awake()
    {
        panel = panelGo.GetComponent<BasePanel>();
    }

    private void Update()
    {
        Profiler.BeginSample("CanvasGroup");
        CanvasGroupFun();
        Profiler.EndSample();

        Profiler.BeginSample("SetActive");
        ActiveFun();
        Profiler.EndSample();
    }

    void CanvasGroupFun()
    {
        for (int i = 0; i < num; i++)
        {
            panel.OnEnter();
            panel.OnExit();
        }
    }

    void ActiveFun()
    {
        for (int i = 0; i < num; i++)
        {
            panelGo.SetActive(true);
            panelGo.SetActive(false);
        }
        
    }
}

将num设为1000次结果如图

SetActive和CanvasGroup调节alpha这两种方法在对单个Panel物体时每帧重复调用性能差距10倍左右


  • 在panel面板下再挂载一个text文本进行测试

num为100次结果如图:

  • SetActive方法中主要是Text.OnEnable()性能消耗大,它会对初始化文本网格的信息(每个文字所在的网格顶点,UV,顶点色等等属性),而这些信息都是储存在数组中(即堆内存中),文本越多,堆内存开销越大,相应GC就产生了

而实际搭建UI场景中肯定不止一个Text那么简单,所以使用SetAcive(true/false)方法是耗时的并产生GC的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值