美橙建站十四年,北京网页设计公司济南兴田德润简介图片,品牌网站设计有哪些建议,论坛网站设计unity UI如何开启#xff08;显示#xff09;或者关闭#xff08;隐藏#xff09;Panel界面#xff0c;相信大家都是知道的#xff0c;但是如何做最好呢#xff1f;
可能大家一般开启/关闭界面的方法就是直接SetActive吧。这样做通常是可以的#xff0c;简答快速地解决…unity UI如何开启显示或者关闭隐藏Panel界面相信大家都是知道的但是如何做最好呢
可能大家一般开启/关闭界面的方法就是直接SetActive吧。这样做通常是可以的简答快速地解决需求但是它又两个问题 第一Disable掉的物体上面的脚本也不运行了而很多时候我们需要那个脚本运行。这样就不能用挂在自己身上脚本把自己SetActive(true)或者SetActive(false)。如果把自己的引用给另外一个脚本来对自己SetActive(true)或者SetActive(false)又会造成多余的耦合并不符合OOP设计理念。 第二Disable掉的物体重新SetActive(true)会造成较大的性能消耗如果此界面draw call较多会有明显的延迟。
不用SetActive(true)/(false)之后我们还有什么其他方法解决问题吗
以下是大家可能想到的其他方法它们也各有各的问题
方法Scale改为000再改为1,1,1 问题改回后draw call加倍大量垃圾回收
方法将界面移除Canvas这个父物体 问题改回后draw call加倍大量垃圾回收而且新增父物体增加额外引用耦合
方法放在Camera的某个culling层上 问题改回后draw call加倍大量垃圾回收只对screen space-camera有效
方法Canvas.enable false 问题改回后延迟严重而且不方便使用
这些都不好那你说什么方法可行呢
这个解决方法就是给Panel加一个CanvasGroup,上面提到的问题在它身上都不会发生
若要显示
GetComponentCanvasGroup().alpha 1;
GetComponentCanvasGroup().interactable true;
GetComponentCanvasGroup().blocksRaycasts true;
若要隐藏
GetComponentCanvasGroup().alpha 0;
GetComponentCanvasGroup().interactable false;
GetComponentCanvasGroup().blocksRaycasts false;
使用Profiler工具分析CanvasGroup组件
首先创建一个BasePanel脚本通过CanvasGroup组件来实现UI面板的显示(OnEnter)和隐藏(OnExit)。这里的BasePanel相当于是UIPanel的基类了这里我只是抽出了一部分等以后有空了把简易的UI管理类也一起讲了。
[RequireComponent(typeof(CanvasGroup))]
public class BasePanel : MonoBehaviour
{private CanvasGroup m_CanvasGroup;private void Awake(){m_CanvasGroup GetComponentCanvasGroup();}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.GetComponentBasePanel();}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次结果如图