Unity Timeline でタイピングアニメーションみたいな事をする

# はじめに

*こんにちは、のんびりエンジニアのたっつーです。*
*[ブログ](https://www.fast-system.jp/)を運営しているのでよろしければ見てください。*

文字をタイピング風にアニメーションさせれると嬉しいよねって事で、以下のTwitterの後半にできる「RIKAI !!」をアニメーションで表示するスクリプトを作った。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">Unity の Timeline にテキストを逐次で出すスクリプトを書いてみた。日本語は使い方忘れたので明日やる！あと色々派手にする予定。 <a href="https://t.co/98NR3XMf4k">pic.twitter.com/98NR3XMf4k</a></p>&mdash; たっつー（ささきたかし） (@kingyo222) <a href="https://twitter.com/kingyo222/status/1037698269910945793?ref_src=twsrc%5Etfw">2018年9月6日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# 実装

## TextMeshPro で文字を追加

Unityの最新版では「TextMeshPro」が標準で使えるようになっているのでこれを利用します、なお標準ではフォントがアルファベットしか使えないので日本語（ひならが、カタカナ、漢字）を使う場合は、フォントデータをダウンロードして使う必要があります。

- メニューから「TextMeshPro」「Font Asset Creator」を選択する。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/227880/fab8656b-a565-ef47-2283-2ed11d45da4e.png)

- 「Import TMP Essentials」を選択する
![image.png](https://qiita-image-store.s3.amazonaws.com/0/227880/93f81516-4739-b287-84bd-37dc0486bd74.png)

- Hierarchyから、シーンを選択して右クリックから「TextMeshPro - Text」を選択する。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/227880/69d65dbb-3844-6865-3d9f-907643bcf4bf.png)

- テキストに「RIKAI !!」を入力し、表示位置を上下左右中央揃えにする。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/227880/072576a2-e743-20cb-78d5-65520da181f4.png)

## タイピング風のアニメーションスクリプトを追加

- 以下の２つのスクリプトをAssetsフォルダに追加します。

```C#:TextPlayableAsset.cs
using UnityEngine;
using UnityEngine.Playables;

[System.Serializable]
public class TextPlayableAsset : PlayableAsset
{
    public ExposedReference<GameObject> charaObj;
    // public string text;

    // Factory method that generates a playable based on this asset
    public override Playable CreatePlayable(PlayableGraph graph, GameObject go)
    {
        var behaviour = new TextPlayableBehaviour();
        behaviour.charaObject = charaObj.Resolve(graph.GetResolver());
        // behaviour.text = text;
        return ScriptPlayable<TextPlayableBehaviour>.Create(graph, behaviour);
    }
}
```

```C#:
using TMPro;
using UnityEngine;
using UnityEngine.Playables;

// A behaviour that is attached to a playable
public class TextPlayableBehaviour : PlayableBehaviour
{
    public GameObject charaObject;
    private string text;

    // Called when the owning graph starts playing
    public override void OnGraphStart(Playable playable) {
        this.text = this.charaObject.GetComponent<TextMeshPro>().text;
        this.charaObject.GetComponent<TextMeshPro>().text = "";
    }

	// Called when the owning graph stops playing
	public override void OnGraphStop(Playable playable) {
        this.charaObject.GetComponent<TextMeshPro>().text = this.text;
	}

	// Called when the state of the playable is set to Play
	public override void OnBehaviourPlay(Playable playable, FrameData info) {

    }

    // Called when the state of the playable is set to Paused
    public override void OnBehaviourPause(Playable playable, FrameData info) {
		
	}

    // Called each frame while the state is set to Play
    public override void ProcessFrame(Playable playable, FrameData info, object playerData)
    {
        // PlayableTrackのClip上でシークバーが移動するたびに呼ばれ続ける（PrepareFrameの後）
        if (charaObject == null) { return; }
        var percent = (float)playable.GetTime() / (float)playable.GetDuration();

        this.charaObject.GetComponent<TextMeshPro>().text =
            this.text.Substring(0, (int)Mathf.Round(this.text.Length * percent));
    }
}
```

- こんな感じで配置される
![image.png](https://qiita-image-store.s3.amazonaws.com/0/227880/bab137e7-9d43-c7e0-4d93-baa5c44a1e8e.png)

## Timeline を追加

- Assetsで右クリックメニューから、Timelineを追加
![image.png](https://qiita-image-store.s3.amazonaws.com/0/227880/f1a9e6cc-22ad-c7e2-4171-13115139b8c0.png)

- 作成したTimelineを、Hierarchyにドラッグアンドドロップで追加する。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/227880/79cdb0d2-0e72-c316-8007-0e9a89471010.png)

- Timelineウィンドウから追加したタイムラインを選択する
![image.png](https://qiita-image-store.s3.amazonaws.com/0/227880/c8e7f964-e5f7-d095-88a1-e52ce684530a.png)

- Playable Track を追加する
![image.png](https://qiita-image-store.s3.amazonaws.com/0/227880/fa5aa4c9-c5bb-f66d-580a-43faddbc0227.png)

- タイムラインを右クリックし、「Add Text　Playable Asset」を選択する
![image.png](https://qiita-image-store.s3.amazonaws.com/0/227880/62dc8fd7-7c80-c8b5-0d67-6f6356812d41.png)

- こんな感じになる。
![rikai.mov.gif](https://qiita-image-store.s3.amazonaws.com/0/227880/0671aead-8454-79a8-eebe-170a3f88a443.gif)

# ソースコード

遅くなりましたがソースコード公開します（2018/09/24）
https://github.com/fastsystem/unity-text-typing-animation

# まとめ

Timeline のスクリプトは意外と簡単で、進捗（0％～100％）で何かさせたいような作業を自分が考えたスクリプトに簡単に置き換え可能になります、そこで今回のような物を作成してみました。
ぜひみなさんも使ってみていただければと思います。

*よければ ブログ「[初心者向けUnity情報サイト](https://www.fast-system.jp/)」の方にも色々記載しているのでぜひご参照いただければと思います。*