Почему Unity Tilemap.HasSyncTileCallback () вызывает скачки задержки при установке плиток на карту тайлов? - PullRequest
0 голосов
/ 25 апреля 2020

Я использую 2d систему плиток Unity для своей игры, и она отлично работает для старых версий игры. В этой новой версии я генерирую куски размером 20x20, когда игрок движется, поскольку мир генерируется процедурно. Все очень производительно, кроме тех случаев, когда я укладываю плитки. Когда я делаю это, я получаю Tilemap.HasSyncTileCallback () в своем профилировщике, и это очень дорого, из-за чего моя система всплывает вокруг пары кадров и генерирует мусор. Есть ли способ обойти это?

Я вызываю следующие функции:

terrainMap.SetTile(tempVect, StaticDatabase.database.Tiles[chunk.tiles[i, j].tileIDs[0]]); terrainMap.SetTileFlags(tempVect, TileFlags.None); terrainMap.SetColor(tempVect, chunk.tiles[i, j].tileColors[0]);

Я также запускал код только с помощью функции SetTile и все еще имел плохую производительность.

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

В настоящее время я использую систему плиток Unity для графики и коллайдеров, так как у меня есть собственная реализация плиток в форме «MyTile». Должен ли я просто прекратить использование системы плиток Unity и попробовать другие методы, такие как объединение объектов или бомбардировка текстур?

Два источника, один с той же проблемой https://forum.unity.com/threads/settile-is-slow-plans-to-implement-ecs-pattern-to-tilemap.639619/

Другой с Бомбардировка текстур https://forum.unity.com/threads/tile-map-accelerator-high-performance-shader-based-tile-map-renderer.708413/

Спасибо за помощь!

1 Ответ

0 голосов
/ 25 апреля 2020

Я нашел решение после тестирования нескольких разных методов. Вызов SetTile () для большого l oop любого вида имеет высокую производительность. Есть еще один метод, который вы можете вызвать, если вам нужно разместить много плиток, например SetTileBlock (). Это позволяет избежать этих Tilemap.TileSyncCallbacks и refreshTile () или, по крайней мере, сохранить их как минимум.

Вот мой код для того, что я сделал, чтобы исправить это в моем вопросе выше.

public void loadTerrainFromChunk(MyChunk chunk)
    {
        Tile[] terrainTiles = new Tile[chunkSize * chunkSize];
        for (int i = 0; i < chunkSize; i++)
        {
            for (int j = 0; j < chunkSize; j++)
            {
                Vector3Int tempVect = new Vector3Int(chunk.tiles[i, j].index.x, chunk.tiles[i, j].index.y, 0);
                int tempIndex = i + (j * chunkSize);
                if (chunk.tiles[i, j].tileIDs[0] != -1)
                {
                    terrainTiles[tempIndex] = ScriptableObject.CreateInstance("Tile") as Tile;
                    terrainTiles[tempIndex].sprite = StaticDatabase.database.Tiles[chunk.tiles[i, j].tileIDs[0]].sprite;
                    terrainTiles[tempIndex].name = StaticDatabase.database.Tiles[chunk.tiles[i, j].tileIDs[0]].name;
                    Matrix4x4 matrix = Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(0f, 0f, 90f * seededRandom.Next(3)), Vector3.one);
                    terrainTiles[tempIndex].transform = matrix;
                    terrainTiles[tempIndex].flags = TileFlags.None;
                    terrainTiles[tempIndex].color = chunk.tiles[i, j].tileColors[0];

                }
            }
        }

        terrainMap.SetTilesBlock(new BoundsInt(chunk.index.x*chunkSize, chunk.index.y*chunkSize, 1, chunkSize, chunkSize, 1), terrainTiles);

    }

Все, что вам нужно сделать, это

1) Создать массив для хранения ваших плиток.

2) Создать экземпляры плиток, которые вы хотите, и загрузить их в массив.

3) (Необязательно) Измените плитки в этом массиве.

4) Загрузите этот массив в функцию SetTilesBlock ().

Хорошего дня!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...