ゲームエフェクトデザイナーのブログ | A Real-Time VFX Artist's Blog

About Making Materials on UE, Making Tools with C#, etc

C# RPG風にテキストメッセージを1文字ずつ表示させる

案外ググっても出てこないのでメモ。

テストで作ったものはこちら。
Button1 を押すと Label1 に文字列を一文字ずつ表示します。

f:id:moko_03_25:20180924201537g:plain

やっていることは以下のような感じ。

・各行ごとに string型の変数を用意

・foreach で string型の引数から1文字ずつ取り出して文字列に「追加」する
 そして少し待機させる
 空白文字だった場合は待機させない

・行間も待機させる


空白文字の場合は待機させると不自然になり、スルーすると自然になりました。

コードはこんな感じ。
非同期処理について全くと言って良いほど理解していない状態なので、その点ご了承ください。

private async void button1_ClickAsync(object sender, EventArgs e)
{
    string s1 = "ほにゃらら は レベルアップしました!" + "\r\n";
    string s2 = "\r\n" + "ちから が 2 あがった!";
    string s3 = "\r\n" + "すばやさ が 1 あがった!";
    string s4 = "\r\n" + "かしこさ が 2 あがった!";

    string output = "";

    int waitTimeChar = 50; // 一文字の待機時間
    int waitTimeLine = 300; // 行間の待機時間

    await OutputMessage(s1);
    await Task.Delay(waitTimeLine);

    await OutputMessage(s2);
    await Task.Delay(waitTimeLine);

    await OutputMessage(s4);
    await Task.Delay(waitTimeLine);

    await OutputMessage(s3);


    // 関数:1文字ずつ表示する
    async Task OutputMessage(string s)
    {
        // foreachで1文字ずつ処理(後半)
        foreach (char c in s)
        {
            // 1文字追加
            output += c.ToString();

            // ラベルに表示
            this.label1.Text = output;

            // 空白文字以外にディレイさせる
            if ("" != c.ToString())
            {
                // ディレイ
                await Task.Delay(waitTimeChar);
            }
        }
    }
}


以上、参考になれば幸いです。

※自分用のメモ

文字列から1文字取得する、文字列内の文字を列挙する - .NET Tips (VB.NET,C#...)

C# で Thread.Sleep はあきまへん

async、awaitそしてTaskについて(非同期とは何なのか) - SE(たぶん)の雑感記

C# Taskの待ちかた集

非同期メソッド - C# によるプログラミング入門 | ++C++; // 未確認飛行 C