Jump to content
Unity Insider Forum

"ArgumentOutOfRangeException", kann eigentlich nicht sein


RLe

Recommended Posts

Hallo, liebe Forum-Community,

ich bin mit Unity C# noch unerfahren, und ich möchte einen "laufenden Text" erstellen, also so einen, wo man die Buchstaben beim Schreiben sieht, ihr versteht, was ich meine. Den Text holt sich mein Text-Reader-Script aus einer .txt Datei. Nun scheint aber irgendwas bei meinem Quellcode falsch zu sein, der Compiler wirft die ganze Zeit "ArgumentOutOfRangeException: Index and length must refer to a location within the string.
Parameter name: length
System.String.Substring (System.Int32 startIndex, System.Int32 length) (at <e1319b7195c343e79b385cd3aa43f5dc>:0)
TextReader+<ShowText>d__10.MoveNext () (at Assets/Scripts/TextReader.cs:56)
UnityEngine.SetupCoroutine.InvokeMoveNext (System.Collections.IEnumerator enumerator, System.IntPtr returnValueAddress) (at C:/buildslave/unity/build/Runtime/Export/Coroutines.cs:17)
" aus, was aber nicht sein kann. Ich hab mich mehrmals vergewissert, meine Variablen liegen genau im richtigen Limit. Außerdem kommt der Text komisch raus, das heißt die erste Zeile fehlt, und es werden Worte wiederholt.

In der angefügten Datei ist mein Code. Zu meiner .txt-Datei: Die Codierung ist UTF-8, habe sie erst kürzlich geändert, da sonst offenbar kein Einlesen möglich wäre.

Forum_frage.PNG

Edit: Eine Änderung im Code hat schon mal geholfen, er wiederholt keine Worte. Aber das Problem, dass das erste Element übersehen wird, besteht weiterhin. Hier ist der veränderte Teil:

Forum_frage2.PNG

Mir ist inzwischen aufgefallen, dass das erste List-Element nicht in "sentence" eingetragen wird, der Wert von "sentence" bleibt beim ersten Schleifendurchlauf aus irgendeinem Grund "". Es hat, soweit ich erkennen kann, mit der Methode Substring zu tun, aber ich finde den Fehler einfach nicht.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Deine Schleife "beginnt" bei 0 (i = 0). Da in der Zeile:

sentence += sentences[index].Substring(0,i)

im ersten Durchlauf i noch 0 ist, bildet sich dein Substring aus (0,0). Dadurch wird dein Wert im ersten Durchlauf 0 sein.

Edit: Bitte zukünftig Code auch als Code einfügen und nicht als Bild. Das macht das Lesen und Antworten deutlich leichter.

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Danke schon mal! Okay, das mit den Bildern mache ich in Zukunft nicht mehr. Aber jetzt noch eine Frage, und zwar macht der Typ in dem Video da es genauso, und bei dem scheint es zu funktionieren:

(6:44)

Klar, es hat offensichtlich damit zu tun, dass der nur einen String initialisiert, bei mir sind es ja einige. Aber ich verstehe es trotzdem nicht so ganz.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ein gravierender Unterschied ist bei der Zuweisung an "sentence" zu sehen.

In deinem Code

sentence += sentences[index].Substring(0,i)

und im Video

sentence = sentences[index].Substring(0,i);

Der Unterschied ist das kleine "+" bei der Zuweisung. In deinem Fall ergänzt du deine Variable "sentence" immer um die komplette Zeichenfolge die dir die Funktion Substring() liefert, im Beispielvideo wird sie aber ersetzt.

Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 10 Stunden schrieb TurTur:

Ein gravierender Unterschied ist bei der Zuweisung an "sentence" zu sehen.

In deinem Code


sentence += sentences[index].Substring(0,i)

und im Video


sentence = sentences[index].Substring(0,i);

Der Unterschied ist das kleine "+" bei der Zuweisung. In deinem Fall ergänzt du deine Variable "sentence" immer um die komplette Zeichenfolge die dir die Funktion Substring() liefert, im Beispielvideo wird sie aber ersetzt.

Danke für den Hinweis. Hatte es auch schon bemerkt, wenn ich es korrigiere habe ich aber wieder das Problem, dass immer nur ein Teil meines Textes angezeigt wird.

Was ich möchte: Ich drücke eine Taste, und es wird der erste Satz angezeigt. Ich drücke die gleiche Taste noch mal, und ein weiterer Satz wird hinzugefügt, und so weiter, bis der letzte Satz da ist. Aber was ich probiere, es ergibt nicht das, was ich will.

Im Moment ist mein Code:

IEnumerator ShowText()
    {
        for (int i = 0, index_count = 0; i <= file_text.Length; i++, index_count++)
        {
            sentence = "";
            for (int l = 0; l < i; l++)
                sentence += sentences[l];
            sentence += file_text.Substring(i, i - 1 + sentences[index].Length);
            text_object.text = sentence;
            yield return new WaitForSeconds(delay);
        }
    }

Link zu diesem Kommentar
Auf anderen Seiten teilen

Der eigentliche Fehler ist, du veränderst in der Update-Routine den Wert für "index" direkt nach dem Aufruf der Coroutine, was dazu führt, das nach dem ersten Zeichen (aus der gewünschten Zeile/Feldelement) die restliche Zeichenfolge aus der folgenden Zeile/Feldelement extrahiert wird. Beim Start der Coroutine wird diese bis zur Yield-Anweisung ausgeführt und dann die Anweisung "index ++" in der Update-Routine.

Eine Möglichkeit wäre in der Update-Routine "indes ++;" vor dem Aufruf der Coroutine zu setzen. Dann müsstest du "index" allerdings mit -1 initialisieren.
Oder du pufferst den Inhalt aus "Sentences[index]" in eine lokale Variable (innerhalb der Coroutine) und greifst in der Schleife darauf zu.

Gruß

Turtur

Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 11 Stunden schrieb TurTur:

Der eigentliche Fehler ist, du veränderst in der Update-Routine den Wert für "index" direkt nach dem Aufruf der Coroutine, was dazu führt, das nach dem ersten Zeichen (aus der gewünschten Zeile/Feldelement) die restliche Zeichenfolge aus der folgenden Zeile/Feldelement extrahiert wird. Beim Start der Coroutine wird diese bis zur Yield-Anweisung ausgeführt und dann die Anweisung "index ++" in der Update-Routine.

Eine Möglichkeit wäre in der Update-Routine "indes ++;" vor dem Aufruf der Coroutine zu setzen. Dann müsstest du "index" allerdings mit -1 initialisieren.
Oder du pufferst den Inhalt aus "Sentences[index]" in eine lokale Variable (innerhalb der Coroutine) und greifst in der Schleife darauf zu.

Gruß

Turtur

Vielen Dank für deine Hilfe! Habe jetzt die Lösung gefunden, und zwar geht es so:

for (int i = 0; i <= sentences[index - 1].Length; i++)
        {
            text_object.text = file_text + sentences[index - 1].Substring(0, i);
            if (i == sentences[index - 1].Length)
                file_text += sentences[index - 1];
            yield return new WaitForSeconds(delay);
        }

Link zu diesem Kommentar
Auf anderen Seiten teilen

Archiviert

Dieses Thema ist jetzt archiviert und für weitere Antworten gesperrt.

×
×
  • Neu erstellen...