IEnumerator BuildText() { int runsThisFrame = 0; string[] textArray = hasMarkup ? MarkupManager.SplitByTag(targetText) : new string[1] { targetText }; // If this is additive text, make sure we include the previous text. _currentText = previousText; // We need a storage variable to separate out the nested text. string nestedText = ""; // aka curText // Build the text by moving through each part for (int i = 0; i < textArray.Length; i++) { string section = textArray[i]; // Tags will always be odd-indexed. Even if there are two in a row, there will be an empty array between them. bool isOdd = i % 2 == 1; if (isOdd && hasMarkup) { // store the current text into something that can be referenced as a restart point as tagged sections of text get added or removed. nestedText = _currentText; NESTED_TEXT childNode = new NESTED_TEXT($"<{section}>", textArray, i); while (!childNode.isDone) { //during each loop we need to call the next step in the markup process // First set a boolean to indicate if a step was taken bool stepped = childNode.Step(); _currentText = nestedText + childNode.displayText; // Only yield if a step was taken in building the string if (stepped) { runsThisFrame++; int maxRunsPerFrame = skip ? 5 : charactersPerFrame; // Handles fast forwarding // Move the variable declaration up? if (runsThisFrame == maxRunsPerFrame) { runsThisFrame = 0; yield return(new WaitForSeconds(skip ? 0.01f : 0.01f * renderSpeed)); } } } i = childNode.arrayProgress + 1; } else // Not processing markup { for (int j = 0; j < section.Length; j++) { _currentText += section[j]; runsThisFrame++; int maxRunsPerFrame = skip ? 5 : charactersPerFrame; // Handles fast forwarding // Move the variable declaration up? if (runsThisFrame == maxRunsPerFrame) { runsThisFrame = 0; yield return(new WaitForSeconds(skip ? 0.01f : 0.01f * renderSpeed)); } } } } // Signal the end of the build process buildProcess = null; }
// Function to step through the array during the build process // Returns true if a step was taken, false when a step must be made from a lower lever of the nesting. public bool Step() { if (isDone) // The current enclosure is done { return(true); } if (childMarkupNode != null && !childMarkupNode.isDone) // There is a subEnclosure still being processed. { return(childMarkupNode.Step()); } else // Any children have already been processed, to this point. { if (currentText == targetText) // we've finished the current text node and need to check for more children. { if (allSpeechAndTagsArray.Length > _arrayProgress + 1) // There is another entry in the array. { string nextPart = allSpeechAndTagsArray[_arrayProgress + 1]; bool isATag = ((_arrayProgress + 1) % 2 != 0); if (isATag) // the next part is a tag { if ($"<{nextPart}>" == endTag) // We have reached the closing tag and can end the step at this level. { _isDone = true; // Check for parents if (parentMarkupNode != null) { string taggedText = startTag + currentText + endTag; parentMarkupNode.currentText += taggedText; parentMarkupNode.targetText += taggedText; // Bypass the next value of the array UpdateArrayProgress(2); } } else // we have hit a tag within a tag { childMarkupNode = new NESTED_TEXT($"<{nextPart}>", allSpeechAndTagsArray, _arrayProgress + 1); childMarkupNode.parentMarkupNode = this; UpdateArrayProgress(); } } else // The next part is text to be added { targetText += nextPart; UpdateArrayProgress(); } } else // This is the end of the text. { _isDone = true; } } else // There is still text to build { currentText += targetText[currentText.Length]; // Update the display text, which also means updating any parents if this is a child node. UpdateDisplayText(""); return(true); // a step was taken } } return(false); // is this necessary? }