一:
.GetComponent<>()调用效率低下,尤其是在编辑器外部.避免在任何类型的Update()方法中使用它们.
二:
拖动ScrollView的每个帧都调用OnValueChanged().因此,从某种意义上讲,它等效于Update(),因此您应该避免在此方法中使用.GetComponent<>()调用.
三:
每当更改Canvas上的任何元素时,整个Canvas都必须重建其批次.此操作可能非常昂贵.因此,建议您将UI元素划分为至少两个Canvas,一个用于很少或永远不会更改的元素,而一个则是经常更改的元素.
每当ScrollView滚动整个画布时,都会弄脏它.因此,建议您将每个ScrollView放在单独的Canvas上.
四:
EventSystem.Update()处理场景中的输入检测,使用射线广播在层次结构中进行过滤,以便找到接受此输入的组件.因此,仅在与场景交互时才进行这些计算,例如在滚动ScrollView时.从图形和文本中删除不必要的RaycastTarget属性将缩短此处理时间.可能并没有太大的区别,但是如果您不注意足够的对象,则可以使输入处理时间真正加起来.
五:
使用任何种类的遮罩组件,甚至是RectMask2D,都可以批处理并渲染ScrollView中的所有对象.如果ScrollView中包含很多元素,建议您使用某种合并解决方案.在应用程序商店中有许多可用的方法.
但是,如果您的项目与此项目不兼容,需要持久性元素,则建议您隐藏屏幕外对象以减少性能开销. Transform.SetParent()和GameObject.SetActive()都是资源密集型方法,而是将CanvasGroup组件附加到每个元素并调整alpha值以实现相同的效果.
这是一个静态脚本,用于检测对象是否可见并相应地设置Alpha:
using UnityEngine;
using UnityEngine.UI;
public class ScrollHider : MonoBehaviour {
static public float contentTop;
static public float contentBottom;
static public bool HideObject(GameObject givenObject, CanvasGroup canvasGroup, float givenPosition, float givenHeight) {
if ((Mathf.Abs(givenPosition) + givenHeight > contentTop && Mathf.Abs(givenPosition) + givenHeight < contentBottom) || (Mathf.Abs(givenPosition) > contentTop && Mathf.Abs(givenPosition) < contentBottom)) {
if (canvasGroup.alpha != 1) {