2017-07-03 43 views
0

我想爲我的遊戲製作一個對話框腳本,使用某種自動分類樣式。問題是當我開始遊戲時,它給了我一個錯誤:IndexOutOfRangeException:數組索引超出範圍。在我解決這個問題之後,我失去了自動分型效果,該消息立即出現。統一遊戲自動打字問題的c#對話框腳本

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

通過你的MonoBehaviour閱讀,這就是我看到它這樣做的:

  1. 設置text元素,如果它是不是已經初始化

  2. 複製從text文本內容到變量message

  3. 開始添加的內容到由字符text組件的值字符

  4. 閱讀TextAsset成字符串的集合,每行分裂

  5. 組線

  6. Update()幀的總數,設定文字text的內容爲當前行的字符串值

  7. 檢查用戶是否按下了空格鍵,如果是這樣,則將行索引向上移動

  8. 檢查的最後一行已經超過了,如果是禁用的遊戲對象

這裏有幾流的問題。最大的問題是您的協同程序與Update()打勾之間的競爭。您可能想要將您的調用移動到獨立函數中啓動協程,並使用阻塞變量來確定何時可以或不能觸發例程。

考慮以下幾點:

// 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());  
    } 

}