吹き出しと、感情表現として、ハートマーク、スマイルマーク、涙マークを用意した。
画像はすべてplaneに貼ってある。透明あり画像。
吹き出しの文字は3Dtext。
つねにカメラの方を向くようにする予定。
動きに関してはすべてコルーチンでやっている。
セリフも1文字づつ表示するが、コルーチンで劇的に処理が簡単に書けた。
スマイルマークなんかは、すでにスマイルマークが動いてるときに、悲しい言葉を投げると、コルーチンの二重起動になるので、ややこしい話になる。
古いの止めると、最後にマークを非表示にする処理が飛んでしまう。
flagを使ったり、いったん全部マークを消してしまうなど色々やり方はあると思うけど。
起動中のコルーチンにメッセージを送る仕組みを作りたい。
stopしたときに特定の処理をやって死ぬみたいな仕組みはあるのかな?
コルーチンを止める場合は、以下の記事を抑えておく必要がある
StopCoroutineではコルーチンは完全に止まらない - Qiita
uGUI表示に変更
どうせビルボードにするつもりなら、初めからuGUIのコンポーネントにしてみた。
ロジックはほぼ同じですが、RectTransformへのアクセスになりますね。
planeだったのが、uGUIのImageになります。
↑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; }