Prayer90 Geschrieben 29. Oktober 2020 Melden Share Geschrieben 29. Oktober 2020 Hallo zusammen, ich stehe noch ganz am Anfang mit meinen Unity und C# Kenntnissen, daher entschuldige ich mich schonmal vorab für meine unqualifizierten Fragen. Im Moment versuche ich ein Spiel nachzubauen, was ich früher mal im GM 8 gebaut hatte. Es geht um eine Grid basierte Tower Defense mit zufällig generierten Maps. Die Umgebung soll vorab, in einem auf Zahlen basierten Gitter generiert werden. Dieses wird im zweiten Schritt Zelle für Zelle ausgewertet. Je nach Zellwert werden dann verschiedene Objekte generiert. Meine Frage: Auf welche Art und Weise erstelle ich am besten das Zahlengrid? Zellen müssen per Koordinate ansprechbar und bearbeitbar sein Im GM 8 gab es dafür extra eine Grid Funktionen. Was ich bis jetzt gelesen hatte, kann ich in Unity entweder mit Listen oder mit Arrays arbeiten oder gibts noch eine Alternative? Ich wollte einfach mal horchen wie Ihr Profis in einem solchen Fall vorgehen würdet. Lg Prayer90 Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Cxyda83 Geschrieben 30. Oktober 2020 Melden Share Geschrieben 30. Oktober 2020 moin Prayer90! Da bist du schonmal auf dem richtigen weg mit Arrays oder listen. In dem fall würde ich dir ein Array vorschlagen da sich die größe deines Grids wohl nicht zur laufzeit ändert. Im Prinzip brauchst du dann eine GridCell klasse (oder struct) und eine Grid klasse... Das minimalbeispiel sähe so aus: public class GridCell { public int X; public int Y; public GridCell(int x, int y) { X = x; Y = y; } } public class Grid { public int Width; public int Height; private GridCell[] _grid; public Grid(int width, int height) { Width = width; Height = height; _grid = new GridCell[Width * Height]; InitGridCells(); } private void InitGridCells() { for (int y = 0; y < Height; y++) { for (int x = 0; x < Width; x++) { _grid[y * Height + x] = new GridCell(x, y); } } } public GridCell GetCell(int x, int y) { return _grid[y * Height + x]; } } mit z.B. new Grid(10, 10) erzeugst du ein neues 10x10 großes Grid. Die Zellen werden in einem 1-dimensionalen Array abgelegt und der index der gewünschten Zelle wird mit y * Height + x errechnet. Mal dir das am besten mal auf wenn du nicht verstanden hast wie das funktioniert, das ist finde ich sehr hilfreich :). Die andere möglichkeit wäre ein 2Dimensionales Array. Aber die gängigere variante ist denke ich diese hier. Viel spaß beim durchdenken und coden ! 🙂 Cxyda Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
chrische5 Geschrieben 30. Oktober 2020 Melden Share Geschrieben 30. Oktober 2020 hallo Schau dir doch mal das hier an: könnte helfen christoph Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Prayer90 Geschrieben 1. November 2020 Autor Melden Share Geschrieben 1. November 2020 Ich danke euch beiden für die Antworten, Das Video hat sehr geholfen, ich denke das ist ein Ansatz, mit dem ich weiter arbeiten kann:) Lg Prayer90 Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Prayer90 Geschrieben 2. November 2020 Autor Melden Share Geschrieben 2. November 2020 Grundlegend funktioniert das ganze schonmal. Ich kann mithilfe des Skriptes ein beliebiges Grid erzeugen und innerhalb dessen Werte ändern. Wie kann ich jetzt möglichst einfach, von anderen Objekten auf das erzeugte Gitter zugreifen? Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Cxyda83 Geschrieben 2. November 2020 Melden Share Geschrieben 2. November 2020 Hey Prayer90, da gibt es mehrere möglichkeiten .. aber die einfachste wäre wohl mithilfe des Singleton Patterns kurz gesagt fügst du in deinen constructor von deiner Grid klasse sowas hier ein: public class Grid { // Diese 2 Zeile hier brauchst du public static Grid Instance => _instance; private Grid _instance; // .. hier steht wahrscheinlich anderer code in deiner klasse // und hier dein constructor fügst du noch eine Zeile ein... public Grid(int width, int height) { // und diese Zeile brauchst du noch _instance = this; // mehr constructor code ... } } Dann kannst du aus jedem deiner anderen scripte Grid.Instance aufrufen und hast zugriff auf dein Grid. Du musst allerdings aufpassen das du den constructor (also grid grid = new Grid(10, 10)) aufrufst bevor du irgendwo anders Grid.Instance aufrufst. Sonst bekommst du eine NullreferenceException. An dieser stelle sei noch gesagt das dieser Ansatz einige (unschöne) eigenschaften hat die du oben in dem link zum SingletonPattern nachlesen kannst. Aber fürs erste geht das so Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Prayer90 Geschrieben 4. November 2020 Autor Melden Share Geschrieben 4. November 2020 Ok, das mit der Grid-Übergabe habe ich hinbekommen, Dankeschön. Mittlerweile kann ich analog dem obigen Video ein Grid erzeugen, dieses wie ich es brauche mit Werten füllen. Anschließend wird jede Zelle im Grid ausgelesen und entsprechend dem Wert der Zelle, ein Objekt erzeugt. Das erzeugte Objekt bekommt das Grid übergeben und soll sich anhand der umliegenden Zellen (Werte) ausrichten (s. Anhang). Für jede Richtung (16 Möglichkeiten) hat das Objekt ein separates Mesh. Es werden immer die Zellen nach oben, links, unten und rechts angeschaut, wenn ein entsprechendes Feld angrenzt, dann wird ein bool auf true gesetzt. Je nach Auswertungsergebnis wird der entsprechende Mesh Renderer aktiviert. //Auswertung------------------------------------------------------------- //4 mal true--------------------- //Viereck if (oben == true && rechts == true && unten == true && links == true) {felsen16.GetComponent<MeshRenderer>().enabled = true;} //3 mal--------------------- //oben if (oben == false && rechts == true && unten == true && links == true) { felsen12.GetComponent<MeshRenderer>().enabled = true; } //rechts if (oben == true && rechts == false && unten == true && links == true) { felsen13.GetComponent<MeshRenderer>().enabled = true; } //unten if (oben == true && rechts == true && unten == false && links == true) {felsen10.GetComponent<MeshRenderer>().enabled = true;} //links if (oben == true && rechts == true && unten == true && links == false) { felsen11.GetComponent<MeshRenderer>().enabled = true; } Das funktioniert bis dahin ganz gut (Außenbegrenzung im Anhang). Sowie allerdings mehr als zwei der if Conditions false sind. Bekomme ich eine Fehlermeldung: UnassignedReferenceException: The variable felsen11 of TestGrid has not been assigned //2 mal--------------------- if (oben == false && rechts == false && unten == true && links == true) { felsen11.GetComponent<MeshRenderer>().enabled = true; } Das verstehe ich allerdings nicht, "felsen11" benutzte ich ja in der Abfrage darüber auch und da funktioniert es. 🤔 Kann mir jemand erklären wie der Fehler zustande kommt? Ich stehe gerade völlig auf dem Schlauch. Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Cxyda83 Geschrieben 4. November 2020 Melden Share Geschrieben 4. November 2020 ich vermute mal du hast felsen11 nicht richtig zugewisen. Nur weil du über deinem fehlerhaften code bereits felsen11 verwendest heist das ja nicht das felsen11 da zugewisen ist. Kann ja auch sein das der fall den du da abfragst (3x true) noch nicht eingetreten ist Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Prayer90 Geschrieben 4. November 2020 Autor Melden Share Geschrieben 4. November 2020 Felsen10 bis 13 sind die Begrenzung der Außenränder die braungraue Reihe auf dem Bild. Diese werden im oberen Teil des Codes auch Ordnungsgemäß gesetzt. Der Fall (3x true) tritt daher mehrfach auf. Das ist ja das komische an der Sache. Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Recommended Posts
Archiviert
Dieses Thema ist jetzt archiviert und für weitere Antworten gesperrt.