Was ist die Größenbeschränkung für die Unity 2017.2-Tilemap?


17

Ich habe die Dokumentation zur Tilemap-Funktion von Unity 2017.2 durchgearbeitet.

Beschränkt Unity die maximale Anzahl von Kacheln, die für ein bestimmtes Tilemap-Netz unterstützt werden?

Ich weiß, dass jede Kachel einmal instanziiert wird und zur Laufzeit verwendet wird, um die Quads auf dem Tilemap-Netz zu texturieren. Daher würde ich vermuten, dass die maximale Anzahl der Mesh-Quadrate letztendlich von der Hardware abhängt und mehr oder weniger willkürlich hoch ist.

Ist das eine richtige Annahme oder gibt es eine harte Kappe im Motor?


1
Warum die Gegenstimme? Dies ist eine berechtigte Frage.
Philipp

Antworten:


25

Ihr RAM ist Ihre Grenze .

Die folgenden Tests wurden an einem System mit diesen Spezifikationen durchgeführt:

  • Intel i5-6600
  • 16 GB RAM
  • NVIDIA GeForce GTX 1070
  • Windows 7 Home Premium

Hier ist ein Skript, das ich ausgeführt habe und das eine Tilemap vergrößert, indem es mit einer einzelnen Kachel (32 x 32 Pixel) gefüllt wird. Die Methode Grow()fügt der aktuellen Karte eine weitere Spalte und eine weitere Zeile hinzu. Die Methode wird bei jedem Update 100 Mal aufgerufen.

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++;
    }
}

Nach ein paar Minuten ging meinem Computer der Speicher aus und Unity stürzte ab. Zu diesem Zeitpunkt waren es 8400 x 8400 (70 Millionen) Kacheln, und Unity.exe verbrauchte laut Task-Manager etwas mehr als 11 GB RAM.

Nun, aber was ist mit spärlichen Karten?

Hier ist ein anderes Skript, das eine einzelne Kachel in Schritten von 100 Kacheln an steigenden x- und y-Koordinaten platziert:

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;
    }    
}

Der Speicherbedarf von Unity.exe ist in der Tat sehr gering, was darauf hindeutet, dass leere Kachelsatzzellen fast keinen RAM benötigen. Die FPS sanken jedoch weiter, während der Kachelsatz wuchs. Es erreichte 60 Fps bei 30000 x 30000, 30 Fps bei 60000 x 60000 und 15 Fps bei 90000 x 90000. Die Fps blieben so niedrig, als ich das Skript entfernte, während das Testspiel lief. Diese Verlangsamung resultierte also nicht aus einer Änderung der Tilemap. Es war einfach vom Rendern. Wenn Sie also ein wirklich riesiges Open-World-Spiel erstellen möchten, müssen Sie möglicherweise mehrere kleinere Tilemaps verwenden, die Sie zur Laufzeit erstellen und zerstören.

Schlussfolgerungen: Riesige, aber meist leere Karten belegen nicht viel RAM, stellen jedoch einen Rendering-Engpass dar , selbst wenn sich der größte Teil nicht im Kamera-Ansichtsfenster befindet.

Ich habe dann mit diesem Skript experimentiert, das Tilemaps mit einer bestimmten Größe generiert:

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);
            }
        }
    } 
}

Ich habe dieses Skript verwendet, um eine 8192x8192-Karte zu generieren. Es dauerte ein paar Minuten, aber als das Skript fertig war, lief es mit stetigen 95 Fps.

Fazit: Karten mit Millionen von Kacheln sind zumindest auf Gaming-PCs machbar .


5
Dies ist die schönste Antwort, die ich seit langer Zeit gesehen habe. "Lass es uns herausfinden!" schreibt Skripte, um das System zum Laufen zu bringen Skript- Computer beginnt zu rauchen "Sieht so aus, als ob es Sie nicht einschränkt!" Vielen Dank @Philipp!
Stephan

Wie hoch war die Framerate bei der Erstellung des 8192 ^ 2-Tests? Ich bin gespannt, wie sehr die Bemühungen der Generation das System blockiert haben.
Stephan

1
@Stephan Zero FPS. Wie gesagt, die Generierung dauert mehrere Minuten. Und da dieses Skript seine UpdateMethode während der Generierung nicht verlässt , frieren das Spiel und der Unity-Editor ein, bis die Generierung abgeschlossen ist. Wenn Sie möchten, dass Ihr Spiel während der Kartengenerierung anspricht, verschieben Sie die Generierung auf eine Coroutine, die jeweils einen Block generiert und zwischen diesen Renditen erzielt.
Philipp

@Stephan Übrigens ist es möglicherweise schneller, mit SetTilesBlock alle Kacheln gleichzeitig zu setzen. Aber die Testkarte schnell zu erstellen, war hier nicht mein Ziel.
Philipp

Oh! duh ok Aus irgendeinem Grund dachte ich, dass es unterbrechen würde. Das ist ein interessanter Gedanke. Ich muss dieses Wochenende damit rumspielen. Es scheint noch nicht sehr viele Ergebnisse zu dieser Funktion zu geben, da sie so neu ist. Vielen Dank für die gründliche Antwort! Es hat bereits viel Aufmerksamkeit erregt. Der Nachwelt helfen!
Stephan
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.