steave007 Posted February 2, 2014 Report Share Posted February 2, 2014 Hey Leute, Ich bin etwas verwirrt weil mein ultimativer Weltherrschaftsplan nicht funktioniert: Ich habe eine static var in dem Script "mainApp" static var orderedWp : GameObject[,]; Und hier soll dieser Array verändert werden: #pragma strict static var sizeX : float = 0; static var sizeY : float = 0; static var editMode : boolean = false; //true = hinzufügen, false = löschen var waypoint : GameObject; var ground : GameObject; var wpManager : GameObject; static var nextPos : Vector3 = Vector3(1,0,2); function Generate () { for(var x : int = 0;x<sizeX;x+=4) { for(var y : int = 0;y<sizeY;y+=4) { var newWp = Instantiate(waypoint,nextPos,Quaternion.identity); newWp.transform.parent = wpManager.transform; mainApp.orderedWp[x,y] = newWp; nextPos.z+=4; } nextPos.z = 2; nextPos.x+=4; } } dann krieg ich den Fehler: NullReferenceException: A null value was found where an object instance was required. Warum?? Laut Konsole liegt es an: mainApp.orderedWp[x,y] = newWp; aber newWp ist doch ein GAmeObject Danke, steave007 Link to comment Share on other sites More sharing options...
Thariel Posted February 2, 2014 Report Share Posted February 2, 2014 Nein, es könnte auch ein Transform sein oder sonst was. Instantiate gibt nur ein Object zurück. Mach mal: var newWp = (GameObject)Instantiate(waypoint,nextPos,Quaternion.identity); Hast du das waypoint GameObject im Inspector draufgezogen? Erscheint es in der Hirarchy? Link to comment Share on other sites More sharing options...
steave007 Posted February 2, 2014 Author Report Share Posted February 2, 2014 Draufgezogen hab ich alles und wenn ich es so mache wie du geschrieben hast kommt ein insert semicolon fehler Link to comment Share on other sites More sharing options...
Mark Posted February 2, 2014 Report Share Posted February 2, 2014 Dein Array muss erst erstellt werden: orderedWp = new GameObject[GroßeX, GrößeY, GrößeZ]; Wie man das in UnityScript macht weiß ich nicht, eben wie man jedes andere Array auch erzeugt nehme ich an. Link to comment Share on other sites More sharing options...
steave007 Posted February 2, 2014 Author Report Share Posted February 2, 2014 Habs jetzt so gemacht: static var orderedWp = new GameObject[1000,1000]; Scheint erstmal zu funktionieren. Nur die Begrenzung ist blöd... Danke! Link to comment Share on other sites More sharing options...
kayy Posted February 2, 2014 Report Share Posted February 2, 2014 Nimm eine ArrayList oder ähnliches, die wächst automatisch nach Bedarf. Link to comment Share on other sites More sharing options...
steave007 Posted February 2, 2014 Author Report Share Posted February 2, 2014 Gibst da irgendeine kurze Anleitung zu? Link to comment Share on other sites More sharing options...
steave007 Posted February 2, 2014 Author Report Share Posted February 2, 2014 Wie funktioniert der Zugriff auf diesen Array?? Ich hab jetzt: pathArray.push(mainApp.orderedWp[coordinates.x,coordinates.z]); Im Array coordinates wird ein Vector3 gespeichert. Der Befehl soll also zu dem Array pathArray den jeweils zum Vector3 zugehörigen Punkt liefern. Link to comment Share on other sites More sharing options...
Mark Posted February 3, 2014 Report Share Posted February 3, 2014 Finger weg von ArrayList, wir sind schließlich auch keine Höhlenmenschen mehr. List ist das was du suchst, es gibt zwar noch eine ganze Menge anderer Möglichkeiten aber eine List ist das was am häufigsten verwendet wird und auch am einfachsten zu verstehen ist. List<T> ist eine Klasse die ein drunter liegendes Array automatisch vergrößert wenn der Platz dieses Arrays nicht mehr ausreicht. Darüber musst du dir nicht unbedingt Gedanken machen. Um List<T> zu verwenden brauchst du ein using in C# bzw import in US, und zwar folgendes: using System.Collections.Generic; import System.Collections.Generic; Dir wird ja aufgefallen dass ich List<T> schreibe, die Spitzen Klammern bedeuten hier dass List eine GEnerische Klasse ist und das T gibt an welcher Typ für die List verwendet werden soll, in deinem Fall wäre dies das GameObject, geschrieben wird das ganze dann als: List<GameObject> listeVonGameObjects; In US ist dies leicht anders: var listeVonGameObjects : List.<GameObject>; vor dem Benutzen muss es natürlich erzeugt werden so wie jede andere Instanz auch: listeVonGameObjects = new List<GameObject>(); In US vermutlich so: listeVonGameObjects = List.<GameObject>(); Neue Elemente werden so hinzugefügt: listeVonGameObjects.Add(neuesGameObject); Und so wieder entfernt: listeVonGameObjects.Remove(neuesGameObject); Oder: listeVonGameObjects.RemoveAt(index); Wobei der Index die Position in der List beschreibt. In deinem Ausgangspost hast du ein 3 Dimensionales Array gehabt, das kannst du so direkt nicht mit der List verwenden, da die List 1 Dimensional ist, aber man kann 3D zu 1D Konvertieren, was aber keine gute Idee ist wenn deine Liste wachsen soll. Also entweder dir fällt da etwas schlaues ein oder du versuchst etwas anderes: Das Dictionary! Das Dictionary<TKey, TValue> speichert 2 Werte, einmal ein Schlüssel anhand der Wert gefunden werden kann und eben der Wert. Du könntest die Position als Schlüssel nehmen und das GameObject als Wert: Dictionary<Vector3, GameObject> meinDictionary; Erzeugung funktioniert auf die gleiche Weise wie bei der List, deswegen erspare ich mir diesen Beispielcode mal. Aber interessant ist wiederum das anlegen: Entweder so: Vector3 position = new Vector3(x, y, z); meinDictionary[position] = meinGameObject; oder so: Vector3 position = new Vector3(x, y, z); meinDictionary.Add(position, meinGameObject); Der Unterschied der beiden Methoden ist: Die Variante mit Add wirft eine Exception/Fehler wenn es den Eintrag an der "position" schon gibt. Auslesen geht so: Vector3 position = new Vector3(x, y, z); GameObject meinGameObject = meinDictionary[position]; Oder so: Vector3 position = new Vector3(x, y, z); GameObject meinGameObject; if (meinDictionary.TryGet(position, out meinGameObject)) { ... } Der Unterschied hier ist: Die Erste Variante schmeißt einen Fehler wenn es den Eintrag nicht gibt. Löschen kann man Einträge so: Vector3 position = new Vector3(x, y, z); meinDictionary.Remove(position); Das alles ist natürlich sehr leicht langsamer und komplexer zu verwenden als einfach ein fixes 3 Dimensionales Array, überlege also ob du das brauchst. Link to comment Share on other sites More sharing options...
kayy Posted February 3, 2014 Report Share Posted February 3, 2014 Finger weg von ArrayList, wir sind schließlich auch keine Höhlenmenschen mehr. Sorry für die ArrayList, war mir in Javascript nicht sicher. Volle Zustimmung, Generics sind na klar die erste Wahl Link to comment Share on other sites More sharing options...
Mark Posted February 3, 2014 Report Share Posted February 3, 2014 Mich hat schon gewundert wieso so eine Empfehlung von dir aufkam Link to comment Share on other sites More sharing options...
steave007 Posted February 3, 2014 Author Report Share Posted February 3, 2014 Vielen Dank für den ausführlichen Post. Leider schreib ich allerdings in JavaScript, wo es meines Wissens nach keine Dictionary gibt (ich hab zumindest in der Scripting Reference keine gefunden korrigiert mich wenn ich falsch liege). Da steht nur etwas von Hashtable, ist das was ähnliches? Vielleicht hilft es weiter wenn ich mein Vorhaben genau beschreibe: Ich programmiere gerade am Bresenham-Algorithmus für meine Belegarbeit. Als funktioniert soweit so gut und die Funktion liefert einen Array mit Vector3 Punkten die zum Weg gehören. Nun reichen diese Punkte alleine allerdings nicht, denn ich kann nur mit Waypoints weiterarbeiten die ich nach dem A*-Tutorial gebastelt habe. Deshalb dachte ich mir: Der Script der die Wegpunkte erstellt wirft sie einfach gleich in einen 2D-Array. Erste Dimension: x-Koordinate Zweite Dimension: y(bzw. z)-Koordinate Jetzt will ich praktisch mit meinen Vector3 Variablen den richtigen Wegpunkt auswählen und damit weiter arbeiten können... Was empfehlt ihr mir also zu nehmen? Link to comment Share on other sites More sharing options...
Mark Posted February 3, 2014 Report Share Posted February 3, 2014 Dictionary gehört zu Mono/.Net das geht auch mit UnityScript, auch wenn sich da alles kacke anfühlt und benutzt. Nutz gleich C# :> Aber zu dem was du vorhast: GameObjekte haben immer die Transform Komponente welche dir ihre Position im Raum mitteilen können, wieso also genau ein 2D Array? Ich vermute mal es geht dir dabei um einen schnellen und einfachen Zugriff. Link to comment Share on other sites More sharing options...
steave007 Posted February 4, 2014 Author Report Share Posted February 4, 2014 Ja es geht vor allem um Schnelligkeit, der Bresenham-Algorithmus muss am Ende schneller sein als A* Ich bin durch den restlichen Code an US gebunden... Also gibt es vielleicht doch irgendeine Möglichkeit das so ähnlich zu machen wie ich das geplant habe? Weil sonst müsste der Bresenham-Algorithmus statt mit Koordinaten ja die ganze Zeit schon mit Waypoint.transform.position arbeiten... Link to comment Share on other sites More sharing options...
Mark Posted February 5, 2014 Report Share Posted February 5, 2014 Du kannst C# aber mit US gemeinsam benutzen. Aber zum Thema: Musst du denn dein 2D Array wachsen lassen? Link to comment Share on other sites More sharing options...
steave007 Posted February 5, 2014 Author Report Share Posted February 5, 2014 Theoretisch legt der Nutzer die Breite und Höhe des Testfeldes selbst fest. Also Add und Push brauch ich theoretisch nicht wenn du das meinst. Link to comment Share on other sites More sharing options...
Mark Posted February 6, 2014 Report Share Posted February 6, 2014 Dann reicht ein 2D Array doch aus. Link to comment Share on other sites More sharing options...
steave007 Posted February 6, 2014 Author Report Share Posted February 6, 2014 Ja aber wie greife ich darauf den wieder zu?? for(var i : int = 0; i<=coordinates.length; i++) { pathArray.push(mainApp.orderedWp[coordinates[i].x,coordinates[i].z]); } Klappt nicht Link to comment Share on other sites More sharing options...
Sascha Posted February 7, 2014 Report Share Posted February 7, 2014 Weil push keine Funktion eines Arrays ist. zweiDimensionalesArray[index1][index2] = blub; Link to comment Share on other sites More sharing options...
steave007 Posted February 7, 2014 Author Report Share Posted February 7, 2014 Aber das oben ist ja kein 2D Array mehr. Da soll ja nur aus dem wieder ausgelesen werden. Den 2D Array hab ich so wie du geschreiben hast zugewiesen: mainApp.orderedWp[x,y] = newWp; Link to comment Share on other sites More sharing options...
Sascha Posted February 8, 2014 Report Share Posted February 8, 2014 Öh, mein Fehler. Hab die Java-Schreibweise verwendet -.- Link to comment Share on other sites More sharing options...
Mark Posted February 8, 2014 Report Share Posted February 8, 2014 Geht in C# aber auch in US vermutlich ebenso, sind dann halt Jagged Arrays, funktionieren sogar schneller als Multidimensionale Arrays, auch wenn der Setup aufwändiger ist. Link to comment Share on other sites More sharing options...
Sascha Posted February 8, 2014 Report Share Posted February 8, 2014 Ah, deswegen hat meine Kurzrecherche vorm Posten auch ergeben dass das geht... Da ich in C# gefühlt noch nie 2-dimensionale Arrays beutzt habe... Link to comment Share on other sites More sharing options...
Recommended Posts
Archived
This topic is now archived and is closed to further replies.