質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.37%

  • Unity

    5845questions

    Unityは、ユニティテクノロジーが開発したゲームエンジンです。 主にモバイルやブラウザ向けのゲーム製作に利用されていましたが、3Dの重力付きゲームが簡単に作成できることから需要が増え、現在はマルチプラットフォームに対応しています。 言語はC言語/C++で書かれていますが、C#、JavaScript、Booで書かれたコードにも対応しています。

Unityでの文字の扱い(1文字ずつ表示、リッチテキスト)

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 888

kagaribisou

score 6

Unityでリッチテキスト+αを考慮して、1文字ずつ表示したいと考えています。
また、文章の作成は。.txtファイルを読み込んで行おうとしています。
実行すると、エラーメッセージが出ることなく、Unityが反応しなくなります。
OutputChar関数が問題を起こしていると思っていますがお手上げです。
アドバイスよろしくお願いします。

Test.txt
[text]<speed=1.00>速度を変える</speed>
[end]

コード
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System.IO;
using System.Text;
using System;

public class TextDisplay : MonoBehaviour {

    public string[] sentences;//文章を格納する
    public string file;//分ける前の文章
    [SerializeField] Text uiText; //UiTextへの参照
    [SerializeField] Text uiName;  //UiNameへの参照

    [SerializeField]
    [Range(0.001f, 0.3f)]
    float intervalForCharDisplay = 0.05f;//1文字の表示にかける時間



    private int currentSentenceNum = -1;//現在表示している文章番号
    private string currentSentence = string.Empty;//現在の文字列

    private float timeTmpDisplay = 0.0f;//文字表示の一時的なインターバル
    private bool isTmpTime = false;
    private float timeBeganDisplay = 1;//文字列の表示を開始した時間

    [SerializeField] public string filename;// = string.Empty;//読み込みたいファイル名
    private bool isTimerSet = false;
    int displayCharCount = 0;
    string[] endTagStack = {null,null,null,null,null};
    int tagNestNum = 0;

    // Use this for initialization
    void Start () {
        SetSentence();
        SetNextSentence ();
    }

    // Update is called once per frame
    void Update () {

        //文章の表示完了/未完了
        if (IsDisplayComplete())
        {
            //最後の文章ではない&ボタンが押された
            if((currentSentenceNum + 1) < sentences.Length && Input.GetKeyUp(KeyCode.Space))
            {
                SetNextSentence ();
            }     
        }
        else
        {
            //ボタンが押された
            if (Input.GetKeyUp(KeyCode.Space))
            {
                uiText.text = sentences[currentSentenceNum];
                displayCharCount = sentences[currentSentenceNum].Length;
            }
            else if (isNextCharTime())
            {
                OutputChar();
            }
        }
    }
    //-------------------------------------------------------------------------------
    //文字を出力する
    void OutputChar()
    {
        Debug.Log("callOutputChar");
        displayCharCount++;
        while(currentSentence.Substring(displayCharCount - 1,1) == "<")
        {
            int startIndex = displayCharCount - 1;
            int endIndex = currentSentence.IndexOf(">", startIndex + 1);
            int tagLength = (endIndex - startIndex) + 1;

            bool isCanDChack = (currentSentence.Length - startIndex) > 7;
            bool isTagDelay = false;
            if (isCanDChack)
            {
                Debug.Log("isCanDChack = true");
                isTagDelay = currentSentence.Substring(startIndex + 1, 6) == "/speed" ||
                 currentSentence.Substring(startIndex + 1, 5) == "speed";
            }
            Debug.Log("isTagDelay=" + isTagDelay);
            if(isTagDelay)
            {
                Debug.Log("call delay");
                if (currentSentence.Substring(startIndex,tagLength).Contains("="))
                    timeTmpDisplay = float.Parse(currentSentence.Substring(startIndex + 7, 4));//数値に変換
                currentSentence.Remove(startIndex, tagLength);
                isTmpTime = (isTmpTime == false);//スイッチを入れ替える
                continue;
            }
            else if(currentSentence.Substring(startIndex + 1,1) == "/")
            {
                displayCharCount += tagLength;//タグの文字数だけ表示を進める
                endTagStack[tagNestNum - 1] = null;
                tagNestNum--;
                continue;
            }
            displayCharCount += tagLength;//タグの文字数だけ表示を進める
            string endTag = "</" + currentSentence.Substring(startIndex + 1, tagLength - 1);
            if (endTag.Contains("="))
                endTag = endTag.Remove(endTag.IndexOf("="), endTag.Length - endTag.IndexOf("=") - 1);
            endTagStack[tagNestNum] = endTag;
            tagNestNum++;
        }
        uiText.text = currentSentence.Substring(0, displayCharCount);
        //リッチテキスト用
        if(endTagStack[0] != null)
        {
            for(int i = 1; i < tagNestNum + 1; i++)
            {
                uiText.text += endTagStack[tagNestNum - i];
            }
        }
    }
    //-------------------------------------------------------------------------------
    //次の文章をセットする
    void SetNextSentence()
    {
        Debug.Log("callSetSentence");
        currentSentenceNum++;
        currentSentence = sentences [currentSentenceNum];
        displayCharCount = 0;
        for (int i = 0; i < endTagStack.Length; i++)
            endTagStack[i] = null;
        tagNestNum = 0;
    }
    //-------------------------------------------------------------------------------
    //
    bool IsDisplayComplete()
    {
        return displayCharCount >= sentences[currentSentenceNum].Length;
    }
    //-----------------------------------------------------
    //
    void Readfile()
    {
        //"FileName".txtを読み込む
        TextAsset t = Resources.Load("text/Test", typeof(TextAsset)) as TextAsset;
        file = t.text;

    }

    //-------------------------------------------------------------------------------
    //読み込んだファイルをセットする
    void SetSentence()
    {
        string Type = "";
        int startIndex = 0, endIndex = 0;
        //ファイルを読み込む
        Readfile();
        int textSize = (file.Length - file.Replace("[text]", "").Length)/6;
        sentences = new string[textSize];
        startIndex = file.IndexOf('[');
        Debug.Log(startIndex);
        Debug.Log("file.Length" + file.Length);
        int numSentence = 0;
        while (true)
        {
            endIndex = file.IndexOf(']', startIndex + 1);
            Type = file.Substring(startIndex + 1, (endIndex - startIndex - 1));
            if (Type == "end") break;
            startIndex = file.IndexOf('[', endIndex + 1);//次の命令までのインデックス

            if(Type == "text")
            {
                sentences[numSentence] = file.Substring(endIndex + 1, ((startIndex - 1) - endIndex));
                numSentence++;
                Type = "";
            }
            else if (Type == "name") {
                uiName.text = file.Substring(endIndex + 1, ((startIndex - 1) - endIndex));
                Type = "";
            }
        }
    }
    //-------------------------------------------------------------------------------
    //次の文字を表示する時間になったらtrueを返す関数
    bool isNextCharTime()
    {
        if (isTimerSet)
        {
            float T;
            if (isTmpTime)
                T = timeTmpDisplay;
            else
            {
                T = intervalForCharDisplay;
                timeTmpDisplay = 0.0f;
            }

            if(Time.time - timeBeganDisplay > T)
            {
                isTimerSet = false;
                timeBeganDisplay = 0;
                return true;
            }
            return false;
        }
        isTimerSet = true;
        timeBeganDisplay = Time.time;
        return false;
    }
}
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

check解決した方法

0

代入してませんでした!!!
申し訳ないです。投稿を消したい

コード
//文字を出力する
    void OutputChar()
    {
        Debug.Log("callOutputChar");
        displayCharCount++;
        while(currentSentence.Substring(displayCharCount - 1,1) == "<")
        {
            int startIndex = displayCharCount - 1;
            int endIndex = currentSentence.IndexOf(">", startIndex + 1);
            int tagLength = (endIndex - startIndex) + 1;

            bool isCanDChack = (currentSentence.Length - startIndex) > 7;
            bool isTagDelay = false;
            if (isCanDChack)
            {
                Debug.Log("isCanDChack = true");
                isTagDelay = currentSentence.Substring(startIndex + 1, 6) == "/speed";
                if(!isTagDelay)
                    isTagDelay = currentSentence.Substring(startIndex + 1, 5) == "speed";
            }
            Debug.Log("isTagDelay=" + isTagDelay);
            if(isTagDelay)
            {
                Debug.Log("call delay");
                if (currentSentence.Substring(startIndex,tagLength).Contains("="))
                    timeTmpDisplay = float.Parse(currentSentence.Substring(startIndex + 7, 4));//数値に変換




           ====>
           ====>   "currentSentence =" currentSentence.Remove(startIndex, tagLength);
           ====>





                isTmpTime = (isTmpTime == false);//スイッチを入れ替える
                continue;
            }
            else if(currentSentence.Substring(startIndex + 1,1) == "/")
            {
                displayCharCount += tagLength;//タグの文字数だけ表示を進める
                endTagStack[tagNestNum - 1] = null;
                tagNestNum--;
                continue;
            }
            displayCharCount += tagLength;//タグの文字数だけ表示を進める
            string endTag = "</" + currentSentence.Substring(startIndex + 1, tagLength - 1);
            if (endTag.Contains("="))
                endTag = endTag.Remove(endTag.IndexOf("="), endTag.Length - endTag.IndexOf("=") - 1);
            endTagStack[tagNestNum] = endTag;
            tagNestNum++;
        }
        uiText.text = currentSentence.Substring(0, displayCharCount);
        //リッチテキスト用
        if(endTagStack[0] != null)
        {
            for(int i = 1; i < tagNestNum + 1; i++)
            {
                uiText.text += endTagStack[tagNestNum - i];
            }
        }
    }

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.37%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る

  • Unity

    5845questions

    Unityは、ユニティテクノロジーが開発したゲームエンジンです。 主にモバイルやブラウザ向けのゲーム製作に利用されていましたが、3Dの重力付きゲームが簡単に作成できることから需要が増え、現在はマルチプラットフォームに対応しています。 言語はC言語/C++で書かれていますが、C#、JavaScript、Booで書かれたコードにも対応しています。