Prefab Instantiate 性能提升

Prefab Instantiate performance improvment

所以我有多个类别按钮,每个类别都有 20 多个项目。因此,在按下按钮时进行预制和实例化。问题是当我实例化预制件时,我必须使用名称、精灵、btn 单击事件等信息对其进行初始化。这将需要时间来实例化预制件和游戏挂起。这是代码

        for (int i = 0; i < prefab.Length; i++)
        {
            GameObject go = Instantiate(basePrefab) as GameObject;
            go.SetActive(true);
            go.transform.SetParent(prefabParent, false);
            go.transform.localScale = Vector3.one;
            go.GetComponent<Category>().Init(prefab[i]);
        }

此代码在单击按钮时调用。或者,为了在 start 方法中实现一些性能,我已经在一个空的游戏对象上实例化了一些 basePrefab,然后单击按钮只需更改父级并初始化它们。这种方法会带来一些好处,但游戏仍然会挂起 2 秒,这里是代码

        for (int i = 0; i < prefab.Length; i++)
        {
            GameObject go = InstantiatedGameObject[i];
            go.SetActive(true);
            go.transform.SetParent(prefabParent, false);
            go.transform.localScale = Vector3.one;
            go.GetComponent<Category>().Init(prefab[i]);
        }

任何提高性能的解决方案??

So Here is About prefab contenet: 基本上预制包含背景图像,此图像中的蒙版图像类别图像,选择图像,和 文本。在 init 函数中类别图像更改和文本值更改此外背景包含 init 中的按钮设置此按钮的单击事件

如果你的实例化对象是一个普通对象,你可以改进它池化预制件避免每次实例化和销毁这个对象。你有一个很好的工作流程示例 here

如果您知道类别和类别项目的最大数量,则不必实例化它们。您可以使用根据项目数量激活和停用的插槽。在激活期间,您还可以将它们绑定和取消绑定到对象,您可以使用这些对象为按钮元素分配正确的精灵和文本。

如果您事先不知道类别项目的数量,您仍然可以这样做,但使用分页,如果有很多项目,从用户的角度来看也是更可取的。


public class SomeUI : MonoBehavior
{
    public GameObject categorySlotsParent;
    public GameObject categoryItemSlotsParent;
    public Category[] categories;
    
    CategorySlot[] categorySlots;
    CategoryItemSlot[] categoryItemSlots;

    public void Awake(){
        
        categorySlots = GetComponentsInChildren<CategorySlot>();
        categoryItemSlots = GetComponentsInChildren<CategoryItemSlot>();
        AssignCategories(categories);
        
        if(categories.Length > 0 && categories[0] != null)
            SelectCategory(categories[0]);
    }
    
    void AssignCategories(Category[] categories){
        
        for(int i = 0; i < categorySlots.Length;  i++){
            if(i < categories.Length)
            {
                categorySlots[i].SetActive(true);
                categorySlots[i].AssignCategory(categories[i]);
            }
            else
            {
                categorySlots[i].SetActive(false);
                categorySlots[i].AssignCategory(null);
            }
        }
    }
    
    void AssignCategoryItems(CategoryItem[] categoryItems){
        
        for(int i = 0; i < categorySlots.Length;  i++)
        {
            if(i < categoryItems.Length)
            {
                categoryItemSlots[i].SetActive(true);
                categoryItemSlots[i].AssignCategoryItem(categoryItems[i]);
            }
            else
            {
                categoryItemSlots[i].SetActive(false);
                categoryItemSlots[i].AssignCategoryItem(null);
            }
        }
    }
    
    void SelectCategory(Category category){
        AssignCategoryItems(category.categoryItems);
    }
}