我正在尝试使用某种自动设计风格为我的游戏制作对话框脚本。问题是当我开始游戏时它给我一个错误: IndexOutOfRangeException:数组索引超出范围。我解决了这个问题后,我失去了自动打印效果,消息就会立即出现。
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class texttype : MonoBehaviour {
public float letterPause = 0.2f;
//public AudioClip[] typeSound1;
//public int next;
string message;
public GameObject textB;
public Text text;
public TextAsset textf;
public string[] lines;
public int currentLine;
public int endline;
void Start () {
if (text == null) {
text = GetComponent<Text> ();
}
message = text.text;
StartCoroutine(TypeText ());
if (textf != null) {
lines = (textf.text.Split('\n'));
}
if (endline == 0) {
endline = lines.Length - 1;
}
}
IEnumerator TypeText () {
foreach (char letter in message.ToCharArray()) {
text.text += letter;
yield return 0;
yield return new WaitForSeconds (letterPause);
}
}
void Update () {
text.text = lines [currentLine];
if (Input.GetKeyDown (KeyCode.Space)) {
currentLine += 1;
}
if (currentLine > endline) {
textB.SetActive(false);
}
}
}
答案 0 :(得分:0)
通过MonoBehaviour阅读,这就是我所看到的:
设置text
元素(如果尚未初始化)
将文本内容从text
复制到变量message
开始将message
的内容逐个添加到text
组件的值字符
将TextAsset
读入字符串集合,每行拆分
设置总行数
在Update()
框架上,将text
的文字内容设置为当前行的字符串值
检查用户是否按了空格键,如果是,请将行索引向上移动
检查是否已超出最后一行,如果是,则禁用游戏对象
这里有一些流动问题。最大的问题是你的协程和Update()
tick之间的竞争。您可能希望移动调用以将协程启动到单独的函数中,并使用阻塞变量来确定何时可以或不能触发例程。
请考虑以下事项:
// ignoring the using statements...
public class texttype : MonoBehaviour {
public float letterPause = 0.2f;
//public AudioClip[] typeSound1;
//public int next;
string message;
public GameObject textB;
public Text text;
public TextAsset textf;
public string[] lines;
public int currentLine;
public int endline;
public bool isPrinting;
void Start () {
if (text == null) {
text = GetComponent<Text> ();
}
// it's not clear where you store the full message, but I'm assuming inside textf
// if you have it stored in message or text.text, then you can initialize it here
if (textf != null) {
lines = (textf.text.Split('\n'));
}
if (endline == 0) {
endline = lines.Length - 1;
}
}
IEnumerator TypeText () {
// get current line of text
string current = lines[currentLine];
foreach (char letter in current.ToCharArray()) {
text.text += letter;
yield return 0; // not sure this line is necessary
yield return new WaitForSeconds (letterPause);
}
// unlock and wait for next keypress
isPrinting = false;
}
void Update () {
// if we're already printing a line, we can short-circuit
if (isPrinting) return;
if (Input.GetKeyDown (KeyCode.Space)) {
// move line index
currentLine += 1;
if (currentLine > endline) {
textB.SetActive(false);
return;
}
// start printing
PrintNext();
}
}
void PrintNext() {
// redundant check, but better safe than sorry
if (isPrinting) return;
// lock while printing
isPrinting = true;
StartCoroutine(TypeText ());
}
}