Skip to main content

邪修方法3:停下你每次都重新生成的代码,加入一个简易的对象池来优化生成组件时的性能。

在开始这一篇邪修方法教程之前,我们需要补充一个数据

Unity生成一个Prefeb需要消耗1ms时间

而Udon生成一个虚拟机需要额外消耗1ms的时间。

这个数据你们可以自己去测试,生成一个Udon虚拟机带来的性能需求是巨大的,但是大部分时候我们又不需要一个额外完备的对象池来解决这个问题。这个时候我就推荐在脚本中增加一个简易的对象池来优化这方面。

这个对象池的写法也很简单,如下:

//以下代码是从实践中复制的,命名啥的就先不管吧,你们看看就好.jpg

//
private int DishQuantity;

public void UpdateShoppingTrolley()
  {
  GeneratedShoppingTrolley(DishQuantity);
  InitShoppingTrolley(DishQuantity);
  }

//生成需要的模块
private void GeneratedShoppingTrolley(int DishQuantity)
        {
            //1:检查需要的按钮数量
            if (DishQuantity > ShoppingTrolleyButtons.Length)
            {
                //创建新数组
                GameObject[] NewShoppingTrolleyButtons = new GameObject[DishQuantity];
                //复制旧数组
                for (int i = 0; i < ShoppingTrolleyButtons.Length; i++)
                {
                    NewShoppingTrolleyButtons[i] = ShoppingTrolleyButtons[i];
                }
                //创建新按钮
                for (int i = ShoppingTrolleyButtons.Length; i < DishQuantity; i++)
                {
                    NewShoppingTrolleyButtons[i] = Instantiate(ShoppingTrolleyButtonPrefab, ShoppingTrolleyButtonParent);
                }
                //替换旧数组
                ShoppingTrolleyButtons = NewShoppingTrolleyButtons;
                //更新购物车按钮
            }
            else if (DishQuantity < ShoppingTrolleyButtons.Length)
            {
                //创建新数组
                GameObject[] NewShoppingTrolleyButtons = new GameObject[DishQuantity];
                //复制旧数组
                for (int i = 0; i < DishQuantity; i++)
                {
                    NewShoppingTrolleyButtons[i] = ShoppingTrolleyButtons[i];
                }
                //删除多余按钮
                for (int i = DishQuantity; i < ShoppingTrolleyButtons.Length; i++)
                {
                    Destroy(ShoppingTrolleyButtons[i].gameObject);
                }
                //更新数组
                ShoppingTrolleyButtons = NewShoppingTrolleyButtons;
            }

  private void InitShoppingTrolley()
    {
    for (int i = 0; i < DishQuantity; i++)
            {
                int ChooseDish = ChooseDishes[i];
                //获取按钮组件
                UdonBehaviour ButtonComponent = ShoppingTrolleyButtons[i].GetComponent<UdonBehaviour>();
                if (ButtonComponent == null)
                {
                    DebugTextUpdate($"购物车按钮组件获取失败:请联系管理员并重新进入世界");
                    continue;
                }
                //设置按钮索引
                ButtonComponent.SetProgramVariable("Index", i);
                ButtonComponent.SetProgramVariable("PlayerUseMenu", this);
                ButtonComponent.SetProgramVariable("DishIndex", ChooseDish);
                //设置按钮名称
                ButtonComponent.SetProgramVariable("DishName", DishName[ChooseDish]);
                //设置按钮数量
                ButtonComponent.SetProgramVariable("DishQuantity", DishPrice[ChooseDish]);
                ButtonComponent.SendCustomEvent("InitButton");
            }

    }

子脚本则通过InitButton事件进行初始化,即可完成复用。