用于统一游戏自动输入问题的c#对话框脚本

时间:2017-07-03 17:45:03

标签: c# unity3d

我正在尝试使用某种自动设计风格为我的游戏制作对话框脚本。问题是当我开始游戏时它给我一个错误: 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);
        }

    }
}

1 个答案:

答案 0 :(得分:0)

通过MonoBehaviour阅读,这就是我所看到的:

  1. 设置text元素(如果尚未初始化)

  2. 将文本内容从text复制到变量message

  3. 开始将message的内容逐个添加到text组件的值字符

  4. TextAsset读入字符串集合,每行拆分

  5. 设置总行数

  6. Update()框架上,将text的文字内容设置为当前行的字符串值

  7. 检查用户是否按了空格键,如果是,请将行索引向上移动

  8. 检查是否已超出最后一行,如果是,则禁用游戏对象

  9. 这里有一些流动问题。最大的问题是你的协程和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 ());      
        }
    
    }