La tua RAM è il tuo limite .
I seguenti test sono stati eseguiti su un sistema con queste specifiche:
- Intel i5-6600
- 16 GB di RAM
- NVIDIA GeForce GTX 1070
- Windows 7 Home Premium
Ecco uno script che ho eseguito che fa crescere una piastrella riempiendola con una singola tessera (32x32 pixel). Il metodo Grow()
aggiunge un'altra colonna e un'altra riga alla mappa corrente. Il metodo viene chiamato 100 volte ogni aggiornamento.
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++;
}
}
Dopo alcuni minuti, il mio computer ha esaurito la memoria e Unity si è bloccato. A quel punto era di 8400x8400 (70 milioni) di riquadri e Unity.exe consumava poco più di 11 GB di RAM secondo il task manager.
Bene, ma per quanto riguarda le mappe sparse ?
Ecco uno script diverso che posizionava una singola tessera aumentando le coordinate xey con incrementi di 100 tessere:
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;
}
}
L'impronta di memoria di Unity.exe è infatti aumentata molto poco, il che suggerisce che celle vuote del set di tessere non richiedono quasi RAM. Tuttavia, l'FPS ha continuato a cadere mentre il set di piastrelle stava crescendo. Ha raggiunto 60 Fps a 30000x30000, 30 Fps a 60000x60000 e 15 Fps a 90000x90000. Gli Fps sono rimasti così bassi quando ho rimosso lo script mentre il test-game era in esecuzione. Quindi questo rallentamento non è dovuto alla modifica della tilemap. Era semplicemente dal renderlo. Quindi, quando si desidera creare un gioco open world davvero enorme, potrebbe essere necessario utilizzare più tilemap più piccole che si creano e si distruggono in fase di esecuzione.
Conclusioni: le tilemap enormi ma per lo più vuote non usano molta RAM, ma rappresentano un collo di bottiglia nel rendering , anche quando la maggior parte di esse non si trova nel viewport della telecamera.
Ho quindi sperimentato questo script che genera tilemap con una determinata dimensione:
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);
}
}
}
}
Ho usato questo script per generare una mappa 8192x8192. Ci sono voluti alcuni minuti, ma quando la sceneggiatura è terminata, ha funzionato a 95 Fps costanti.
Conclusione: le mappe con milioni di riquadri sono fattibili, almeno sui PC da gioco .