Unity: переполнение памяти на устройстве Android на 800 игровых объектов - PullRequest
1 голос
/ 10 мая 2019

Я хочу попробовать показать много GameObjects на одном экране. Если я предварительно загрузил 777 Monsters (Prefab (включая текст и изображение)), я получаю исключение «недостаточно памяти» на устройстве Android.

Как мне справиться с этим или сделать это лучше? Я новичок в Unity.

Может кто-нибудь сказать мне, почему у меня есть около 14k объектов в Unity-Profiler? Смотрите скриншот ниже:

Profiler screenshot

Загрузка монстров:

GlobalGameVars.monsterImages = new List<Sprite>(Resources.LoadAll<Sprite>("Monsters"));

Мой код:

public class MonsterPreviewManager : MonoBehaviour
{
    public GameObject monsterPreviewPrefab;

    void Start()
    {
        LoadAllMonsters();
    }

    public void LoadAllMonsters()
    {
        List<Sprite> allMonsterImages = GlobalGameVars.monsterImages;

        if (allMonsterImages == null)
        {
            return;
        }

        GameObject newMonsterPreviewPrefab;

        foreach (Sprite sprite in allMonsterImages)
        {
            newMonsterPreviewPrefab = (GameObject)Instantiate(monsterPreviewPrefab, GameObject.FindGameObjectWithTag("MainContent").transform);

            MonsterPreview monsterPreview = newMonsterPreviewPrefab.GetComponent<MonsterPreview>();

            Image monsterImage = monsterPreview.monsterImage;

            monsterPreview.monsterName.text = sprite.name;

            var tempColor = monsterImage.color;
            tempColor.a = 1f;

            monsterImage.color = tempColor;
            monsterImage.overrideSprite = sprite;

            newMonsterPreviewPrefab.SetActive(true);
        }
    }
}

public class MonsterPreview : MonoBehaviour
{
    public Image monsterImage;
    public Text monsterName;


    void Start()
    {
        enabled = false;
    }
}

Исключение (отладка ADB)

05-10 10:18:04.438  2037  2134 D Unity   : Unloading 884 Unused Serialized files (Serialized files now loaded: 0)
05-10 10:18:04.486  2037  2052 D Unity   : UnloadTime: 40.446615 ms
05-10 10:18:04.521  2037  2052 D Unity   : System memory in use before: 30.3 MB.
05-10 10:18:04.530  2037  2052 D Unity   : System memory in use after: 30.4 MB.
05-10 10:18:04.530  2037  2052 D Unity   : 
05-10 10:18:04.530  2037  2052 D Unity   : Unloading 3 unused Assets to reduce memory usage. Loaded Objects now: 2259.
05-10 10:18:04.530  2037  2052 D Unity   : Total: 9.076693 ms (FindLiveObjects: 0.649769 ms CreateObjectMapping: 0.361231 ms MarkObjects: 8.016384 ms  DeleteObjects: 0.046615 ms)
05-10 10:18:04.530  2037  2052 D Unity   : 
05-10 10:18:06.975  2037  2052 D Unity   : Could not allocate memory: System out of memory!
05-10 10:18:06.975  2037  2052 D Unity   : Trying to allocate: 8388609B with 16 alignment. MemoryLabel: Texture
05-10 10:18:06.975  2037  2052 D Unity   : Allocation happened at: Line:77 in ./Runtime/Utilities/dynamic_array.h
05-10 10:18:06.975  2037  2052 D Unity   : Memory overview
05-10 10:18:06.975  2037  2052 D Unity   : 
05-10 10:18:06.975  2037  2052 D Unity   : [ ALLOC_DEFAULT ] used: 23943538B | peak: 36890011B | reserved: 25201090B 
05-10 10:18:06.975  2037  2052 D Unity   : [ ALLOC_TEMP_JOB_1_FRAME ] used: 0B | peak: 0B | reserved: 1048576B 
05-10 10:18:06.975  2037  2052 D Unity   : [ ALLOC_TEMP_JOB_2_FRAMES ] used: 0B | peak: 0B | reserved: 1048576B 
05-10 10:18:06.975  2037  2052 D Unity   : [ ALLOC_TEMP_JOB_4_FRAMES ] used: 0B | peak: 0B | reserved: 13631488B 
05-10 10:18:06.975  2037  2052 D Unity   : [ ALLOC_TEMP_JOB_ASYNC ] used: 0B | peak: 0B | reserved: 1048576B 
05-10 10:18:06.975  2037  2052 D Unity   : [ ALLOC_GAMEOBJECT ] used: 2880842B | peak: 2880914B | reserved: 3274637B 
05-10 10:18:06.975  2037  2052 D Unity   : [ ALLOC_GFX ] used: 571814937B | peak: 580203611B | reserved: 571851576B 
05-10 10:18:06.975  2037  2052 D Unity   : [ ALLOC_PROFILER ] used: 1586772B | peak: 1591092B | reserved: 1650303B 
05-10 10:18:06.975  2037  2052 D Unity   : [ ALLOC_TEMP_THREAD ] used: 323064B | peak: 0B | reserved: 3768320B 
05-10 10:18:07.116  2037  2052 E Unity   : Could not allocate memory: System out of memory!
05-10 10:18:07.116  2037  2052 E Unity   : Trying to allocate: 8388609B with 16 alignment. MemoryLabel: Texture
05-10 10:18:07.116  2037  2052 E Unity   : Allocation happened at: Line:77 in ./Runtime/Utilities/dynamic_array.h
05-10 10:18:07.116  2037  2052 E Unity   : Memory overview
05-10 10:18:07.116  2037  2052 E Unity   : 
05-10 10:18:07.116  2037  2052 E Unity   : [ ALLOC_DEFAULT ] used: 23943538B | peak: 36890011B | reserved: 25201090B 
05-10 10:18:07.116  2037  2052 E Unity   : [ ALLOC_TEMP_JOB_1_FRAME ] used: 0B | peak: 0B | reserved: 1048576B 
05-10 10:18:07.116  2037  2052 E Unity   : [ ALLOC_TEMP_JOB_2_FRAMES ] used: 0B | peak: 0B | reserved: 1048576B 
05-10 10:18:07.116  2037  2052 E Unity   : [ ALLOC_TEMP_JOB_4_FRAMES ] used: 0B | peak: 0B | reserved: 13631488B 
05-10 10:18:07.116  2037  2052 E Unity   : [ ALLOC_TEMP_JOB_ASYNC ] used: 0B | peak: 0B | reserved: 1048576B 
05-10 10:18:07.116  2037  2052 E Unity   : [ ALLOC_GAMEOBJECT ] used: 2880842B | peak: 2880914B | reserved: 3274637B 
05-10 10:18:07.116  2037  2052 E Unity   : [ ALLOC_GFX ] used: 571814937B | peak: 580203611B | reserved: 571851576B 
05-10 10:18:07.116  2037  2052 E Unity   : [ ALLOC_PROFILER ] used: 1586772B | peak: 1591092B | reserved: 1650303B 
05-10 10:18:07.116  2037  2052 E Unity   : [ ALLOC_TEMP_THREAD ] used: 323064B | peak: 0B | reserved: 3768320B 

1 Ответ

0 голосов
/ 14 мая 2019

Вы должны использовать Атлас Спрайта. Кроме того, я вижу, что ваши спрайты имеют статическую переменную, что не очень хорошая идея, это может вызвать некоторые утечки памяти и показать неправильный спрайт. Это уже случилось со мной.

Вы спросили меня в комментарии, как случайным образом назначить Атлас Sprite объекту-монстру. Вы должны использовать этот ответ , чтобы получить один спрайт. Тогда вам, вероятно, придется переименовать вашего монстра в «monster-1», ... «monster-777», а затем написать что-то вроде:

void Start()
{
  AtlasLoader atlasLoader = new AtlasLoader("monsters");
  for(int i = 1; i <= atlasLoader.atlasCount(); i++) {
     int randomInt = Random.Range(1, atlasLoader.atlasCount());
     // probably check if this int isn't already used to avoid duplicates
     Sprite ball = atlasLoader.getAtlas("monster-" + randomInt);
     // Assign this ball to your monster
  }

}

конечно, это псевдокод, я не тестировал его, и вам нужно заменить комментарии своим собственным кодом.

...