uGUIを使って文字列を表示するにはTextを使います。このTextを使って一文字ずつランダムに動かす方法を紹介します。UIの文字でも場所によっては動いている方が楽しいですね〜
UIのTextを一文字ずつ動かす方法
UGUIのTextはModifyMeshメソッドを使うことで、文字を構成するポリゴンにアクセスすることが出来ます。各ポリゴンの頂点座標を配列として得られるので、その頂点座標を一文字ごとに、違った方向に動かすことで文字がバラバラの動きをします。
文字を構成するポリゴンは4頂点ではなく、6頂点で構成されるので注意が必要です。次のような並びになっているようです。
したがって、頂点配列の頂点を6個ごとにばらばらの方向に動かすことで上のような文字の動きが実現できます。
ランダムに動かす方法はなんでも良いのですが、ここでは半径Rの円周上をランダムに指すベクトルを方向ベクトルとして使っています。
では、具体的な実装方法を紹介します。
uGUIでTextを配置する
まずはuGUIでTextを配置します。ヒエラルキービューから「Create」→「UI」→「Text」を選択し、インスペクタから適当な文字を設定して下さい。文字の設定はText欄から行います。その他にも、FontやFont Size、Colorなども調整します。
テキストを動かすスクリプトを作成する
続いて、文字を動かすためのスクリプトを作成します。プロジェクトビューで右クリックして「Create」→「C# Script」を選択し、「TextController」という名前で保存して下さい。
スクリプトが作成できたら次のプログラムを入力して下さい。
using UnityEngine.EventSystems; using System.Collections.Generic; public class TextController : BaseMeshEffect { float time = 0; float radius = 1.5f; public override void ModifyMesh ( UnityEngine.UI.VertexHelper vh) { if (!IsActive()) return; List<UIVertex> vertices = new List<UIVertex>(); vh.GetUIVertexStream(vertices); TextMove(ref vertices); vh.Clear(); vh.AddUIVertexTriangleStream(vertices); } void TextMove( ref List<UIVertex> vertices ) { for (int c = 0; c < vertices.Count; c += 6) { float rad = Random.Range(0,360) * Mathf.Deg2Rad; Vector3 dir = new Vector3 (radius * Mathf.Cos (rad), radius * Mathf.Sin (rad), 0); for(int i = 0; i < 6; i++) { var vert = vertices [c+i]; vert.position = vert.position + dir; vertices [c+i] = vert; } } } void Update() { time += Time.deltaTime; if (time > 0.05f) { time = 0; base.GetComponent<Graphic> ().SetVerticesDirty (); } } }
uGUIのTextはBaseMeshEffectクラスのModifyMeshメソッドをオーバーライドすることで、テキストの表示に使われているポリゴンの頂点にアクセス出来るようになります。
このあたり、Unity5.1、5.2、5.3とどんどん仕様が変わっているようなので、バージョンによってはうまく動かないかもしれません。上のプログラムはUniy5.6で動作を確認しています。
取り出した頂点をTextMoveメソッドの引数に渡しています。TextMoveメソッドの中では6頂点ごとにランダムなベクトルを定義して、頂点座標をベクトル方向に移動させています。
最後にUpdateメソッドから逐次SetVerticesDirtyメソッドを呼ぶことで、文字が動くアニメーションを再生することが出来ます。
おまけ(もっと、もにょもにょ動かす)
上の例では、文字を構成する6頂点はまとめて同じ方向に動かしていましたが、これを1頂点ごとに方向も長さもランダムな方向に動かすと、さらにもにょっとした動きになりました。
こんな感じです。綺麗かどうかは置いておいて(笑)
TextMoveメソッドの中は次のようになっています。頂点2と頂点3、頂点0と頂点5は同じ座標を指すので、同じ方向のベクトルを与えています。
Vector3[] dirs = new Vector3[6]; for (int i = 0; i < 6; i++) { float rad = Random.Range (0, 360) * Mathf.Deg2Rad; float r = radius + 6.5f * Random.value; Vector3 dir = new Vector3 (r * Mathf.Cos (rad), r * Mathf.Sin (rad), 0); dirs [i] = dir; } dirs [3] = dirs [2]; dirs [5] = dirs [0]; for(int i = 0; i < 6; i++) { var vert = vertices [c+i]; vert.position = vert.position + dirs[i]; vertices [c+i] = vert; }
まとめ
ModifyMeshメソッドをオーバーライドすることで、uGUIのTextの各頂点座標にアクセスする方法を紹介しました。動かし方はまだまだバリエーションが出せると思うので、是非試してみて下さいね〜