Unity入門：今週悩んだことと。コルーチンとGUIアニメーション

##はじめに
今週勉強したことをまとめています。

初めまして、HITOMI(男)です。現在Unityを勉強しています。今週勉強したこと、悩んだことをここに書き残します。

2月28日に新作MacBookが届きました。本来は3/8日に届く予定だったのですが、8日も早く届いたのでかなり嬉しいです。新しいPCも届いたことなので、これから今までできなかったハイポリゴンモデルの制作に励んでいきたいと思っています。

さて、私はUnityの勉強のため3D横スクロールゲームを開発しています。そこで今週悩んだことや、詰まったとこをここに書き残そうと思います。


今週(3月1〜3/7日)詰まったところ。
・コルーチンの呼び出し方。
・GUIのアニメーション。
・吹き出しクラス読み込みクラスをどのように実行するか。



今週は吹き出しアニメーション(漫画とかでキャラクターが話す時に出てくるやつ)を自動で読み出すアニメーションをプログラムで実装するために試行錯誤をしていました。
具体的には、吹き出し口が表示されて一定感覚で言葉が進んでいき、話終わると自動で消えていく。というプログラムです。これを実装するために色々調べ、トライアンドエラーを繰り返しました。その中で今回特に詰まったことを紹介します。




##引っかかったコルーチン

まずテキストを一定感覚で表示させるプログラムを作ろうと考えました。webでプログラムについて調べていたところ、すでに実装している人の記事を見つけたので、それを参考にしてプログラムを書くことにしました。

参考にした記事。
[感情表現と吹き出し台詞](http://yasu9780.hatenablog.com/entry/2017/01/28/201003)


ここの記事で紹介されているコルーチンを利用して、一定感覚で文字を表示させるプログラムを書いてみましたが、うまくいきませんでした。

どうやらこのコルーチンはスクリプトをオブジェクトのコンポーネントに関連づけないと上手く動かないようです。（もしかしたら他の要因があるのかもしれません）

初めコルーチンを実装するプログラムを下記のように書いていました。

吹き出しのクラス(SpeechBubble.cs)

```c#:skinShape.rb
public class CSpeechBubble : MonoBehaviour
{
    private  GameObject m_TextObj;
}

public CSpeechBubble(GameObject _canvas)
{
        m_TextObj = new GameObject("TextString");
        m_TextObj.AddComponent<Text>();
        Text tx = m_TextObj.GetComponent<Text>();
}

//コルーチン
IEnumerator SetSpeech(SSpeech _speech)
{
//一文字づつ表示させるプログラム
}
```
SpeechBubble.csがテキストを表示させるGameObjectを持っており、
SpeechBubbleはUIManagerから呼び出される形となっています。

そして**SpeechBubble.csは何もオブジェクトのコンポーネントに関連づけしていない状態でした**


この状態でコルーチン関数のSetSpeechを呼び出しても、全く反応がありませんでした。
どうやら、コルーチンを実装するときは、オブジェクトのコンポーネントに関連づけなければならないようです。(なぜかはまだ調べていません。)


解決策として(あまりカチッとした解決策ではありませんが)
呼び出しクラスからこのスクリプトをオブジェクトに関連づけるように変更しました。
変更すると、うまく動きました。

```c#:UIManager
GameObject speechBubble = new GameObject("BubbleString");
		speechBubble.AddComponent<CSpeechBubble>();
		m_SpeechBubble = speechBubble.GetComponent<CSpeechBubble>();
		m_SpeechBubble.Start(m_Canvas);
		speechBubble.transform.parent = m_Canvas.transform;
		
```


ここにかなり時間を費やしてしまいました。




##イベント等も外部テキストから読み込める形にしたい。
当然この吹き出しはテキストファイルから読み込んで変更できるように作っているのですが、何かイベント等も管理できるように改変したいなと思いました。

現在、私は吹き出しプログラムの内容を外部テキストに書いており、以下のような形で書いています。
(ゲームプログラマになる前に覚えておきたい技術を参考に作りました。)

intervalは文字を進めるはやさの間隔。
autoは自動で次のテキストに進めるかどうか。
autoIntervalは自動で次のテキスト

```
<SpeechBubble>
     <Speech text = "１段目の読み込み",interval="0.1",auto="true",autoInterval="60"></Speech>
     <Speech text = "2段目の読み込み",interval="0.1",auto="true",autoInterval="60"></Speech>
</SpeechBubble>
```

これをイベント等も変更できる形に変えたいと思いました。
そして、色々試行錯誤したのち、以下の形式に変更しました。


```
<EventData　name=“event02”,type = “speak”,trigger=“”,nextEvent=“event03”>
		<TriggerObject type = “box” , event=“event”, position = "12.4,7.0,0.0”, size="1.0,1.0,1.0"></TriggerBox>
		
		//行動制限
		<SpeechBubble position="12.4,7.0,0.0">
        			<Speech speech="左右の矢印を押すと移動できるよ” , type=“timer”></Speak>
        			<Speech speech="上ボタンを押すとジャンプできるよ” , type=“wait”></Speak>
        			<Speech speech="下ボタンを押しても何もないよ。” , type=“wait”></Speak>
    	</SpeechBubble>
		
</Event>
```

ここに表示されているのはイベント２でイベントが終了すると、イベント３に移行する。
イベント移行のトリガーとなるのはトリガーオブジェクトでそのトリガーに触れたらイベントが開始する。内容を話終えると終了する。

これだと、後々イベントを追加したくなった時にいちいちコンパイルしなくてもいいので変更が容易にできるのかなと思っています。これを吹き出しのプログラムを完成したら試そうと考えています。






##アニメーションについて

ではこの吹き出しをアニメーションでフェードイン、フェードアウトさせたいと考えました。どのように実装するか考えた結果、アニメーションコントローラーを用いて制御する方法をとることにしました。理由は新しいことを試してみたいことと、デザイナー と分業ができるからです。

試してみましたが、やはりうまくいかない。


私がやりたかったのは、
①一つのイメージにフェードイン、フェードアウトのアニメーションをつける。
②そのオブジェクトを消去し、フェードイン・アウトのアニメーションのみ抽出。
③そのアニメーションをコントローラーにつける。
④アニメーションさせたいオブジェクトにアニメーションコントローラーをつける。

こうすると任意のオブジェクトをアニメーションさせることができると考えていたのですが、④の部分でオブジェクトが全くアニメーションをしておらず、アニメーションデータを確認したところキーフレームが全くない状態になっていました。


原因についてはまだ検証していないのでまだ分かりませんが、
①アニメーションをつけたオブジェクト を消してしまうと、アニメーションのキー自体も無くなってしまっている。
②単純に操作ミス
③それ以外の要素がある。
だと予想しています。(多分すぐ解決する。)
この件についてはまた来週の書こうと思います。

このアニメーションで詰まっているところなので、来週には解決したいと思っています。
(この記事を書いたあと試してみたら上手く動きました。上手くセーブできていなかったのかな？ということで吹き出しは完成。あとイベント)


##最後に
来週はテキストの吹き出しプログラムを完成させて、外部テキストからイベントを実行できるところまで完成させたいと考えています。(それを実装すれば、プログラムはほぼ終了)。それが終わったら、シーン遷移とクリアを作って、繰り返しできる形にするだけなので、3月中には完成できそうです。
頑張ります！。