You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity ScrollView在Android与iOS平台的重复打开关闭性能劣化问题

Dynamic ScrollView in Unity Causes Severe Mobile Lag After Multiple Open/Close Cycles (Solved)

Hey everyone, I wanted to share a solution to a Unity mobile lag issue that had me stuck for weeks. A month ago, I posted this problem on Stack Overflow but got no responses and the question was automatically removed. Now that I’ve fixed it, I’m reposting here to help anyone else dealing with the same headache.

The Problem

In my Unity game, there’s an inventory screen with a ScrollView that gets dynamically populated with item UI elements at runtime. Everything worked flawlessly in the Unity Editor, but on Android and iOS devices, after players opened and closed the inventory several times, the game slowed to a crawl—almost unplayable.

Root Cause

After digging into Unity’s Profiler connected to a test mobile device, I found the issue: memory leaks from improperly cleaned-up UI objects. Every time the inventory opened, I was instantiating new item prefabs for the ScrollView. But when closing the screen, I only disabled the parent inventory panel instead of destroying or disabling the individual instantiated items. Over repeated cycles, thousands of unused UI objects piled up in memory, triggering constant garbage collection spikes and overwhelming the device’s rendering pipeline.

The Solution

I implemented two key fixes to resolve the lag completely:

1. Clean Up Instantiated Items on Close

Instead of just hiding the inventory panel, explicitly destroy or disable the dynamic item elements when closing the screen. Here’s a simple example of destroying items:

public void CloseInventory()
{
    // Reference to the ScrollView's content container holding item elements
    Transform scrollContent = inventoryScrollView.content.transform;
    
    // Loop through all child items and destroy them
    foreach (Transform childItem in scrollContent)
    {
        Destroy(childItem.gameObject);
    }
    
    // Finally disable the inventory panel
    inventoryPanel.SetActive(false);
}

2. Use an Object Pool for Better Performance

For frequent inventory access, instantiating/destroying objects every time creates unnecessary GC spikes. An object pool reuses existing UI elements instead:

public GameObject inventoryItemPrefab;
private List<GameObject> pooledItems = new List<GameObject>();

// Get a reusable item from the pool (or create a new one if needed)
public GameObject GetPooledItem()
{
    foreach (GameObject item in pooledItems)
    {
        if (!item.activeInHierarchy)
        {
            item.SetActive(true);
            return item;
        }
    }
    
    // No inactive items left—create a new one and add to the pool
    GameObject newItem = Instantiate(inventoryItemPrefab);
    pooledItems.Add(newItem);
    return newItem;
}

// Populate inventory using the pool
public void PopulateInventory(List<Item> playerItems)
{
    foreach (Item item in playerItems)
    {
        GameObject uiItem = GetPooledItem();
        uiItem.transform.SetParent(inventoryScrollView.content.transform, false);
        // Update the item's UI (sprite, count, name, etc.)
        uiItem.GetComponent<InventoryItemUI>().SetItemData(item);
    }
}

// Disable all pooled items when closing inventory
public void CloseInventory()
{
    foreach (GameObject item in pooledItems)
    {
        if (item.activeInHierarchy)
        {
            item.SetActive(false);
        }
    }
    inventoryPanel.SetActive(false);
}

Additional Tips

  • Profile on mobile: Always test with Unity’s Profiler connected to an actual mobile device—desktop/editor behavior can hide mobile-specific performance issues.
  • Check for orphaned references: Ensure you’re not keeping unintended references to UI objects (like in static lists) that prevent garbage collection.

内容的提问来源于stack exchange,提问作者Raffaele Tasso

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 19:52:41