我在我的游戏中使用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函数运行了这段代码,但性能仍然不好。
我有一个想法来解决这个问题,就是在这些变化期间停止回调和刷新,然后手动调用它来停止每次调用的更新,但我甚至不知道如何访问这些参数。
目前,我使用unity的磁贴系统来制作图形和碰撞器,因为我有自己的磁贴实现,以 "MyTile "的形式。我是否应该停止使用unity的磁贴系统,而尝试其他方法,如对象池或纹理轰炸?
两个源头,一个有同样的问题https:/forum.unity.comthreadssettile-is-slow-plans-implement-ecs-pattern-to-tilemap.639619。
另一个是纹理轰炸https:/forum.unity.comthreadstile-map-accelerator-高性能基于着色器的tile-map-renderer.708413。
谢谢你的帮助!我正在使用Unity的二维贴图系统来制作我的游戏,它在旧版本的游戏中运行得非常好。
在测试了多种不同的方法后,我找到了一个解决方案。在任何一种大循环中调用SetTile()都有高性能的代价。如果你需要放置大量的瓷砖,可以调用另一个方法,比如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()函数中。
祝你有个愉快的一天