Unityでもじぴったんのスタンバイアニメーションを再現する!
スポンサーリンク
先週は「Unity1Week」開催中なこともあって、お題の「探す」をテーマにしたゲームを作ろうとしていたのですが、どういう訳か19年ほど前の名作ゲーム「もじぴったん」のゲーム開始前の演出を作成していました。
もう19年も前なのか
1. もじぴったんを再現したソースコード
using System; using System.Collections; using System.Collections.Generic; using DG.Tweening; using UniRx; using UnityEngine; using UnityEngine.UI; public class ImgFade : MonoBehaviour { public RectTransform imageRt; public RectTransform LimitTextRt; public Image image; public CanvasGroup canvasGroup; public CanvasGroup canvasGroupText; private Vector3 saveSize; public Text FadeText; public RectTransform LimitTitleText; public RectTransform LimitText; public RectTransform ReadyText; public Text mReadyText; private int colorType = 0; void Awake () { this.canvasGroup.alpha = 0f; this.canvasGroupText.alpha = 0f; this.mSetYellowText (); } private void mSetYellowText () { string red = "<size=84><color=#ffea00>4</color></size>"; string yellow = "<color=#ff0000>文字</color>"; string white = "<color=#ffffff>のことばを あと</color>"; string yellow2 = "<size=84><color=#ff0000>3</color></size>"; string red2 = "<color=#ffea00>こ</color>"; string white2 = "<color=#ffffff>作れ</color>"; this.FadeText.text = red + yellow + white + yellow2 + red2 + white2; } private void mSetRedText () { string red = "<size=84><color=#fad000>4</color></size>"; string yellow = "<color=#fad000>文字</color>"; string white = "<color=#fad000>のことばを あと</color>"; string yellow2 = "<size=84><color=#fad000>3</color></size>"; string red2 = "<color=#fad000>こ</color>"; string white2 = "<color=#fad000>作れ</color>"; this.FadeText.text = red + yellow + white + yellow2 + red2 + white2; } void Start () { Observable.Timer (TimeSpan.FromSeconds (2)) .Subscribe (_ => { Sequence sequence = DOTween.Sequence () .OnStart (() => { }) .Append (this.imageRt.DOScale (Vector3.one, 1f)).SetEase (Ease.OutCubic) .Join (this.canvasGroup.DOFade (1f, 0.8f)).SetEase (Ease.Linear) .OnComplete (() => { Debug.Log ("Comp"); this.setColor (); // 回数表示 this.mSetLimitText (); }); sequence.Play (); }).AddTo (this); } private void setColor () { Observable.Interval (TimeSpan.FromSeconds (1)) .Subscribe (_ => { if (this.colorType == 0) { this.colorType = 1; this.image.color = Color.red; this.mSetRedText (); } else { this.image.color = new Color (1, 0.4f, 0); this.mSetYellowText (); this.colorType = 0; } }).AddTo (this); } private void mSetLimitText () { Observable.Timer (TimeSpan.FromSeconds (2)) .Subscribe (_ => { this.mLimitTextAnimation (); }).AddTo (this); } private void mLimitTextAnimation () { Sequence sequence = DOTween.Sequence () .Append (this.LimitTitleText.DOScale (Vector3.one, 1f)).SetEase (Ease.OutCubic) .Join (this.LimitText.DOScale (Vector3.one, 1.5f)).SetEase (Ease.OutCubic) .Join (this.canvasGroupText.DOFade (1f, 0.8f)).SetEase (Ease.Linear) .OnComplete (() => { Debug.Log ("Comp mLimitTextAnimation"); this.mLimitTextCoolTime (); }); } private void mLimitTextCoolTime () { Observable.Timer (TimeSpan.FromSeconds (2)) .Subscribe (_ => { this.mLimitTextUpper (); }).AddTo (this); } private void mLimitTextUpper () { Sequence sequence = DOTween.Sequence () .Append (this.LimitTitleText.DOAnchorPosY (400f, 1f)).SetEase (Ease.Linear) .OnComplete (() => { Debug.Log ("Comp mLimitTextUpper"); }); Sequence sequence2 = DOTween.Sequence () .Append (this.LimitText.DOAnchorPosY (280f, 1f)).SetEase (Ease.Linear).SetDelay (0.5f) .OnComplete (() => { Debug.Log ("Comp mLimitTextUpper"); }); Sequence sequence3 = DOTween.Sequence () .Append (this.imageRt.DOAnchorPosY (-450, 1f)).SetEase (Ease.Linear).SetDelay (0.8f) .OnComplete (() => { Debug.Log ("Comp mLimitTextUpper"); this.mSetReadyText (); }); } private void mSetReadyText () { Sequence sequence = DOTween.Sequence () .Append (this.ReadyText.DOAnchorPosX (50f, 1f)).SetEase (Ease.Linear) .AppendInterval (1f) .OnComplete (() => { this.mReadyText.text = "ごー!"; this.mSetGoText (); }); } private void mSetGoText () { Sequence sequence = DOTween.Sequence () .AppendInterval (0.5f) .Append (this.ReadyText.DOAnchorPosX (1300f, 1f)).SetEase (Ease.Linear) .OnComplete (() => { Debug.Log ("mSetGoText"); }); } }
テスト用に作成したのでスクリプトや関数名はすごい適当です。
アニメーションの再現方法は
1 . Dotweenを使ってテキストやイメージのアニメーションを行う
2 . TextのRichTextを適応して動的にテキストの色を変更する
の2つを使用しています。
次にUnity側の実装を見ていきましょう。
思わずなんだこれは!?と思ってしまう散らかりっぷりですね・・・(反省)
最初のimage ですが、ここでは最初のオレンジの帯とテキストの部分を担当しています。
上記動画の部分ですね。最初に表示され、ゲームのルールを知らせます。
次は残り時間などを表示する部分です。
今回は残り回数という表記で表しています (当初作成する予定のゲームルールに合わせて)
ここもUnityのTextをDotweenで動かしています。
あと、ゲームルールを知らせるTextですがタイマー制御で1秒ごとに背景とTextの色とサイズを変更しています。
ソースコードでいうとこの部分に該当
private void mSetYellowText () { string red = "<size=84><color=#ffea00>4</color></size>"; string yellow = "<color=#ff0000>文字</color>"; string white = "<color=#ffffff>のことばを あと</color>"; string yellow2 = "<size=84><color=#ff0000>3</color></size>"; string red2 = "<color=#ffea00>こ</color>"; string white2 = "<color=#ffffff>作れ</color>"; this.FadeText.text = red + yellow + white + yellow2 + red2 + white2; } private void mSetRedText () { string red = "<size=84><color=#fad000>4</color></size>"; string yellow = "<color=#fad000>文字</color>"; string white = "<color=#fad000>のことばを あと</color>"; string yellow2 = "<size=84><color=#fad000>3</color></size>"; string red2 = "<color=#fad000>こ</color>"; string white2 = "<color=#fad000>作れ</color>"; this.FadeText.text = red + yellow + white + yellow2 + red2 + white2; }
RichTextが有効の場合、html形式が有効になるのでソースコード上で動的に変更することが可能です。
細かいアニメーションをやりたい場合はオススメの方法ですね。
最後に左側から出現する「レディー?」部分を見てみましょう。
こちらは左側からTextを中央に移動させ、タイマー管理で文字を変更し右側に移動させています。
色々とゴチャゴチャしていますが1つ1つの処理はとても単純で作りやすいですね
流石もじぴったん
UIアニメーションを入れるだけでゲームの面白さがガツンと上がると思っています。
これからも積極的に導入していきたいですね。