Jump to content
Unity Insider Forum

Random Range


nordseekrabe

Recommended Posts

Moin, liebe Leser

Habe vor wenigen Jahren mit Unity ein kleines "geschrieben", funktioniert ordentlich(Version 2019.2.8f1). Wollte dieses jetzt in ein neues Spiel als Teilaufgabe einbauen (Version 2020.3.19f1). Leider erhalte ich nun stets die Fehlermeldung "Index was outof range. Must be non-negative and less than the  size of the collection". Ich nehme an, dass sich im EventSystem (oder anderswo) von Unity etwas wesentliches geändert hat, sodass man nicht einfach 1 zu1 den Code übertragen kann. Hat bitte jemand einen Tipp oder eine Lösung für mich. Alleine konnte ich das Problem nicht lösen.

Besten Dank und viele Grüße von der Ostseeküste

Peter

ActivatePicture.cs

Link to comment
Share on other sites

Besten Dank für die prompten Antworten. Die GameObjekte wurden korrekt zugewiesen. "Lewo" liegt wohl richtig, wenn er annimmt, dass die Liste eigentlich leer ist. Ich werde also zunächst 9 Gameobjekte (als jeweilige Bildteile) deklarieren; dann in Start() als Teil der Liste addieren. Ob es dann klappt ??

Unklar bleibt mir dennoch, warum der Code in einer früheren Unity-Version anstandslos funktionierte ??!!

Einen schönen Abend wünsche ich und nochmals danke

Peter 

 

Link to comment
Share on other sites

Moin,

muss mich nochmals melden, da ich bislang nicht weiter komme. Nach oben beschriebenen Ergänzungen ( GameObject bildTeil 0- 8 deklariert, theStadt.Add(bildTeil0-8) in Start() ausgeführt, wird ein Assign für "collectedOne" in Zeile "  collectedOne.SetActive(true); " erwartet. CollectedOne ist doch ein durch Random ausgewählter Bildteil von theStadt. Wie und wo kann ich ein assign ausführen ? Oder bin ich da völlig daneben? Wie Sascha bemerkte, die Objekte (acht Bildelemente eines EmptyObjects in der Hierarchy) sind im Inspector unter Objektmanager(der "ActivatePicture enthält) zugewiesen. Mein Problem ist wohl, wie sage ich dem Programm, dass collectedOne eines der oben genannten Bildteile ist ? Sollte das aber nicht durch " GameObject collectedOne = theStadt[UnityEngine.Random.Range(0, theStadt.Count)];" geklärt sein. Bitte nochmals um Euren Rat, bin halt Laie und Anfänger.

Gruß

Peter

Link to comment
Share on other sites

vor 17 Stunden schrieb nordseekrabe:

Mein Problem ist wohl, wie sage ich dem Programm, dass collectedOne eines der oben genannten Bildteile ist ? Sollte das aber nicht durch " GameObject collectedOne = theStadt[UnityEngine.Random.Range(0, theStadt.Count)];" geklärt sein.

Doch, das ist genau richtig. Bei einer Kombination aus diesen beiden Anweisungen

GameObject collectedOne = theStadt[Random.Range(0, theStadt.Count)];
collectedOne.SetActive(true);

können exakt folgende Sachen schiefgehen:

  • theStadt ist null, die Variable referenziert also kein Objekt. Da Unity diese Liste für dich anlegt und du sie auch sonst nirgendwo überschreibst, können wir das ausschließen. Außerdem hättest du eine "NullReferenceException" in deiner Konsole.
  • theStadt ist keine Liste, die nicht (ausschließlich) GameObjects enthält. Dann könntest du das gar nicht erst kompilieren und laufen lassen. Und es ist halt eine List<GameObject>, sieht also auch gut aus.
  • Random.Range gibt einen ungültigen Index zurück. Z.B. ein negativer Wert oder ein größerer Index, als in der Liste vorhanden ist. Da du von "8" auf "theStadt.Count" gegangen bist, bist du da jetzt auch sicher. Aber aus demselben Grund könnte...
  • ...theStadt.Count 0 sein, und dann stopfst du zwei 0 in Random.Range. Da würde es beschweren, aber auch das dürfte eine Meldung in der Konsole geben.
  • Oder der Eintrag in der Liste ist einfach null. Sieht aber nicht danach aus - würdest du im Inspektor dann auch entsprechend als "None" oder "Missing" sehen können, während das Spiel läuft.

Was halt auffällig ist: Du entfernst nach und nach Elemente aus der Liste. Du bist ja seit deinem ersten Post zum Glück von der festen "8" weg, aber dennoch kann die Liste irgendwann leer werden, und beim nächsten Aufruf von "NaechstesTeilbild" würde es entsprechen krachen.

Deine initiale Fehlermeldung besagt, dass du auf einen inkorrekten Index der Liste zugreifen wolltest (z.B. "10" wenn es nur 5 Elemente gibt). Da du jetzt "theStadt.Count" statt "8" benutzt, sollte das aber gefixt sein. Wie sind denn aktuell eigentlich die Symptome? Ich würde nicht davon ausgehen, dass du immer noch dieselbe Fehlermeldung kriegst.

Link to comment
Share on other sites

Also, wie gesagt: Du brauchst da nichts per Hand mit Add in die Liste zu schmeißen. Du kannst die Zeilen 11-19 und 25-33 komplett rausnehmen und die GameObjects im Inspektor direkt in die Liste ziehen.

Die einzige Stelle, an der diese Exception auftreten kann, ist Zeil 51. Und die ist sauber. Ich weiß gerade nicht auswendig, was passiert, wenn man Random.Range mit (0, 0) füttert. Kann sein, dass dann einfach 0 rauskommt. In diesem Fall würdest du bei einer leeren Liste auf Element 0 zugreifen, was es ja nicht gibt - und dann gibt es genau diese Exception. Das ist die einzige Möglichkeit, hier diese Exception zu kriegen.

Achte einmal darauf, was du im Inspektor in der Liste siehst, wenn diese Exception in der Konsole auftaucht. Wenn die Liste nicht leer ist und auch alle Elemente ein GO referenzieren (also kein None oder Missing), dann fliegt der Fehler gar nicht hier, sondern ganz woanders. Wenn du den Fehler kriegst, schau dir auch mal die ganze Fehlermeldung an (draufklicken und dann darunter lesen). Die Fehlermeldung sagt dir, in welchem Script in welcher Zeile die Exception geflogen ist. An dieser Stelle tippe ich schon fast darauf, dass das hier gar nicht das Problematische Script ist.

Link to comment
Share on other sites

Völlig richtig, Zeile 51 wird benannt - im Augenblick der Fehlermeldung sind alle 9 Element im Inspektor unter Objektmanager.ActivatePicture aufgeführt.

TeilKopie der Fehlermeldung:

ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index
System.ThrowHelper.ThrowArgumentOutOfRangeException (System.ExceptionArgument argument, System.ExceptionResource resource) (at <695d1cc93cca45069c528c15c9fdd749>:0)
System.ThrowHelper.ThrowArgumentOutOfRangeException () (at <695d1cc93cca45069c528c15c9fdd749>:0)
System.Collections.Generic.List`1[T].get_Item (System.Int32 index) (at <695d1cc93cca45069c528c15c9fdd749>:0)
ActivatePicture.NaechstesTeilbild () (at Assets/Scripts/Wer kennt das schon/ActivatePicture.cs:51)

danach kommen noch weitere Hinweise(Events, UI.Button, EventSystem aus UnityEngine). Eine weitere Stelle im Script, auch nicht in einer anderen Datei, wird nicht aufgeführt.

Peter

Link to comment
Share on other sites

Dein Hinweis verblüfft mich. Ist mir schon klar, dass ich da irgendwo einen Fehler eingebaut habe. Zu meinem Verständnis sollte ich mehr darstellen:

In der Hierarchy befinden sich neben Main Camera, Eventsystem und einem Canvas (für Buttons, Panels, Inputfield) ein EmptyObject als Objektmanager, dem im Inspector das ActivatePictureScript und ein Stadt.Script (Beschreibungen der einzelnen Objekte) zugewiesen sind. Weiter gibt es in der Hierarchy ein EmptyObject, dem die 9 Teilbilder aus einem Slice des Hauptbildes als Children hinzugefügt sind. Diese Teilbilder werden per Hand in die 9 Elemente der theStadt aus ActivatePicture eingefügt. Das ist ein Szenenbild. Das  zweite Script trägt die weiteren Funktionen (wie Beschreibung zeigen, nächste Szene aufrufen, Eingabe der vermuteten Lösung); ich füge es auch zur Sicherheit bei. Es ist dem InputField im Canvas zugewiesen.

Die "befüllte Liste" ist im Objektmanager. Die Liste im InputFieldScript ist die Liste der verschieden Szenen = Städte; die Randomverteilung hierfür klappt. Zum Verständnis, wenn ich starte und "Button Beschreibung zeigen" drücke, erscheint (erwartungsgemäß) das komplette Bild mit der Beschreibung auf dem Panel. Wenn der "Nächste Szene-Button" gedrückt wird, wird die nächste (leere, keine Bildteile, die sind ja deaktiviert, natürlich mit den Canvas-Objekten) Szene aufgerufen. Nur beim Drücken des "Nächster Bildteil" kommt es zu beschriebener Fehlermeldung , jetzt solte ja nach Zufallsgenerator eines der 9 Bildteile aktiviert werden = erscheinen. Das Problem liegt meines Erachtens an der Random-Verteilung der 9 Bildteile aus Liste "theStadt"   

Danke für Deine Unterstützung, an dem Punkt ist für mich halt kein Weiterkommen.

Schönen Abend und schönes Wochenende

Peter

InputFieldScript.cs

Link to comment
Share on other sites

Evtl. bin ich ja auf nem falschen Weg, aber in ActivatePicture werden die 9 GameObjects "bildTeil0" bis "bildTeil8" privat (weil nicht public) declariert. Daher kannst Du doch eigendlich nichts im Editor zuweisen und dann bleiben die GOs leer.

Link to comment
Share on other sites

vor 15 Minuten schrieb Lewo:

Evtl. bin ich ja auf nem falschen Weg, aber in ActivatePicture werden die 9 GameObjects "bildTeil0" bis "bildTeil8" privat (weil nicht public) declariert. Daher kannst Du doch eigendlich nichts im Editor zuweisen und dann bleiben die GOs leer.

Boah, du hast Recht! @nordseekrabe kann es sein, dass du theStadt im Inspektor befüllt hast, aber dachtest, du würdest bildTeil0-8 befüllen? Das Ergebnis wäre, dass du deine Liste wie im Inspektor hättest, aber zusätzlich noch neunmal null. Allerdings muss ich leider sagen, dass du dann eine NullReferenceException und keine ArgumentOutOfRangeException kriegen würdest 🤔

Link to comment
Share on other sites

Deinem Hinweis folgend bezüglich 2x Script bzw. 2x List habe ich im InputfieldScript die "List(GameObject> _stadt" rausgenommen, stattdessen "public GameObject Gesamtbild" hinzugefügt und die Funktion  "void SceneActivate()" angepasst:     for (var i = 0; i < ActivatePicture.theStadt.Count; i++)
                                                                                                                                      {
                                                                                                                                                 ActivatePicture.theStadt[i].SetActive(false);
                                                                                                                                       }
                                                                                                                                      Stadtbild.SetActive(true);

Damit klappt alles bestens, leider nicht der Click auf "Nächster Bildteil", hier kommt die o.g. Fehlermeldung.

Zu der Frage mit public und private: ist nicht das entscheidende, dass die List<GameObject> theStadt "public" ist, daher erscheinen doch die Elemente im Inspector, denen ich dann die 9 GameObjekte aus der Hierarchy zuweise? Wie Du oben richtig hingewiesen hast, können die Deklarationen (GameObject bildTeil0-8) wegfallen, was ich ja auch ohne Verlust gemacht habe. Sascha, genau, mit der Deklaration hatte ich tatsächlich neben den zugewiesenen Elementen noch weitere 9 Elemente in "theStadt" im Inspektor.

Einen schönen, sonnigen Sonntag und  besten Dank für die Hinweise wünscht

Peter

Link to comment
Share on other sites

P.S. Ergänzend: es fehlte die Objektzuweisung    public GameObject Stadtbild;

                                                                                  ActivatePicture Gesamtbild;

                                                               in Start()   Gesamtbild = GameObject.Find("Objektmanager").GetComponent<ActivatePicture>()

                                              in SceneActivate()    for (var i=0; i< Gesamtbild.theStadt.Count; i++)

                                                                                            Gesamtbild.theStadt[i].SetActive(false);

                                                                                Stadtbild.SetActive(true);

Leider(natürlich) hat sich an der Fehlermeldung nichts geändert.

Link to comment
Share on other sites

vor einer Stunde schrieb nordseekrabe:

Zu der Frage mit public und private: ist nicht das entscheidende, dass die List<GameObject> theStadt "public" ist, daher erscheinen doch die Elemente im Inspector, denen ich dann die 9 GameObjekte aus der Hierarchy zuweise? Wie Du oben richtig hingewiesen hast, können die Deklarationen (GameObject bildTeil0-8) wegfallen, was ich ja auch ohne Verlust gemacht habe. Sascha, genau, mit der Deklaration hatte ich tatsächlich neben den zugewiesenen Elementen noch weitere 9 Elemente in "theStadt" im Inspektor.

Ich würde sagen, du hast dir die Frage selbst beantwortet :)

Langsam wird's leider echt etwas unübersichtlich. Ist Projekt hochladen für dich eine Option?

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...