Answers:
RAM是您的极限。
在具有这些规格的系统上执行了以下测试:
这是我运行的脚本,该脚本通过用单个图块(32x32像素)填充图块图来生成图块图。该方法Grow()
将另一列和另一行添加到当前地图。每次更新都会调用该方法100次。
public class TileTest : MonoBehaviour {
public Tile tile;
private Tilemap tilemap;
public int currentSize;
void Start () {
tilemap = GetComponent<Tilemap>;
Grow();
}
void Update() {
for (var i = 0; i < 100; i++) {
Grow();
}
Debug.Log(currentSize);
}
private void Grow() {
for (int x = 0; x < currentSize; x++) {
tilemap.SetTile(new Vector3Int(x, currentSize, 0), tile);
}
for (int y = 0; y < currentSize; y++) {
tilemap.SetTile(new Vector3Int(currentSize, y, 0), tile);
}
tilemap.SetTile(new Vector3Int(currentSize, currentSize, 0), tile);
currentSize++;
}
}
几分钟后,我的计算机内存不足,Unity崩溃了。当时,根据任务管理器,这是8400x8400(7000万)的图块,Unity.exe消耗的RAM略高于11 GB。
好吧,但是稀疏地图呢?
这是一个不同的脚本,该脚本将单个图块放置在以100个图块为增量的递增x和y坐标处:
public class TileTest : MonoBehaviour {
public Tile tile;
private Tilemap tilemap;
public int currentSize;
void Start () {
tilemap = GetComponent<Tilemap>();
}
void Update() {
tilemap.SetTile(new Vector3Int(currentSize, currentSize, 0), tile);
currentSize+= 100;
}
}
实际上,Unity.exe的内存占用量几乎没有增加,这表明空的tileet单元几乎不需要RAM。但是,随着拼贴的增长,FPS持续下降。它在30000x30000时达到60 Fps,在60000x60000时达到30 Fps,在90000x90000时达到15 Fps。当我在测试游戏运行时删除脚本时,Fps保持如此低的水平。因此,这种变慢并非来自更改图块图。仅仅是从渲染它而已。因此,当您要创建一个非常庞大的开放世界游戏时,可能必须使用在运行时创建和销毁的多个较小的tilemap。
结论:巨大但几乎为空的图块贴图并不会占用太多RAM,但即使大多数视图不在相机视口中,它们也是渲染瓶颈。
然后,我尝试使用此脚本来生成具有给定大小的图块:
public class TileTest : MonoBehaviour {
public Tile tile;
public int xSize;
public int ySize;
void Start () {
Tilemap tilemap = GetComponent<Tilemap>();
for (int x = 0; x < xSize; x++) {
for (int y = 0; y < ySize; y++) {
tilemap.SetTile(new Vector3Int(x, y, 0), tile);
}
}
}
}
我使用此脚本生成了8192x8192地图。花费了几分钟,但脚本完成后,以稳定的95 Fps运行。
结论:至少在游戏PC上,具有数百万个图块的地图是可行的。
Update
在生成过程中并未保留其-方法,因此游戏和Unity编辑器将冻结,直到生成完成为止。如果您希望游戏在地图生成过程中响应,请将生成的图像移至协程中,协程一次生成一个块并在它们之间产生收益。