AIプログラムとかUnityゲーム開発について

探索や学習などを活用したAI系ゲームを作りたいと思います。

感情表現と吹き出しセリフ

f:id:yasu9780:20170128195625g:plain

吹き出しと、感情表現として、ハートマーク、スマイルマーク、涙マークを用意した。
画像はすべてplaneに貼ってある。透明あり画像。

吹き出しの文字は3Dtext。
つねにカメラの方を向くようにする予定。


動きに関してはすべてコルーチンでやっている。
セリフも1文字づつ表示するが、コルーチンで劇的に処理が簡単に書けた。

スマイルマークなんかは、すでにスマイルマークが動いてるときに、悲しい言葉を投げると、コルーチンの二重起動になるので、ややこしい話になる。
古いの止めると、最後にマークを非表示にする処理が飛んでしまう。
flagを使ったり、いったん全部マークを消してしまうなど色々やり方はあると思うけど。

起動中のコルーチンにメッセージを送る仕組みを作りたい。
stopしたときに特定の処理をやって死ぬみたいな仕組みはあるのかな?


コルーチンを止める場合は、以下の記事を抑えておく必要がある
StopCoroutineではコルーチンは完全に止まらない - Qiita

uGUI表示に変更

 どうせビルボードにするつもりなら、初めからuGUIのコンポーネントにしてみた。
 ロジックはほぼ同じですが、RectTransformへのアクセスになりますね。
 planeだったのが、uGUIのImageになります。

f:id:yasu9780:20170129001327p:plain
↑spriteのfliterをbilinerにしないとギザギザになってしまう。

 
 座標変換は、以下の記事を参考
tsubakit1.hateblo.jp
 ただ、サイズも変更しないといけないので手間取りました。カメラから見て奥ほど小さくしないといけない。
 本来写像は距離の逆数で計算だっけ?
 ちょっとよく分からないので、引き算でそれっぽく変換しました。

 3Dだと照明や影の影響を受けるので、アイコンが暗くなってましたが、uGUIならくっきりなので、その点でもよかったです。
 いままでキャラクターの頭上のHP表示などいつも3Dでやってたので、今後はuGUIでやりたいと思います。
 いい機会になりました。

1文字づつ表示するテキスト

string[] good = {
        "またまたあ",
        "ほんとにい?",
        "うれしい",
        "もっと言って",
        "ありがとう",
};

void Update()
{
    if (Input.GetKeyDown("joystick button 0"))//A
    {
        StartCoroutine(setSpeech( good[ UnityEngine.Random.Range(0,good.Length) ] ));
    }
}

    IEnumerator setSpeech(string text)
    {
        for (int i = 0; i <= text.Length; i++)
        {
            FukidasiText.GetComponent<TextMesh>().text = text.Substring(0, i);
            yield return new WaitForSeconds(0.1f);
        }
    }

アイコンを上下に動かす

Slerpを使っているので、サイン波的な単振動な動きになる。
1セット動くたびに既定の位置に強制移動している←もう絶対移動してるから不要
相対移動だけだと、フレームが飛んだタイミングですこしづつベースがづれていく。
本当はiTweenとか使えばいいんだろうけど、なんかなじめない。

Vector3 pos = obj.transform.localPosition;
        float speed = 10f;

        for (int j = 0; j < 7; j++) {
            for (int i = 0; i < speed; i++) {
                obj.transform.localPosition = Vector3.Slerp(pos, pos + Vector3.forward*0.1f, (i/ speed));
                yield return null;
            }
            for (int i = 0; i < speed; i++) {
                obj.transform.localPosition = Vector3.Slerp(pos + Vector3.forward * 0.1f, pos, (i / speed));
                yield return null;
            }
            obj.transform.localPosition = pos;
        }