ミニゲームを作ってUnityを学ぶ![ひつじコレクション編]
###第10回目: UIの作成(1)
前回はゲームに開始・終了の概念とやり直しの機能を実装しました。
今回は各種UIを実装予定だったのですが、思っていたより分量が多くなってしまいそうなため、DOTweenを使ったTweenアニメーションをUIに設定するところまでとなります。
#アセットのインポート
UIを実装する際に必要なアセットをあらかじめプロジェクトにインポートしておきます。
Simple UI
DOTween (HOTween v2)
#UIを管理する
まずはじめにそれぞれのUIについて、表示・非表示の切り替えやアニメーションの設定を一元的に管理するマネージャーを作成しておきます。
- 空オブジェクト「UiManager」をゼロポジションに配置
- スクリプト「UiManager」を作成して上記のUiManagerオブジェクトにアタッチ
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class UiManager : MonoBehaviour {
void Start()
{
GameController.Instance.UiManager = this;
}
}
- GameControllerにプロパティを追加
public UiManager UiManager { get; set; }
作成したUiManagerはどのスクリプトからでも利用できるようにGameControllerに参照を保持させています。
ゲームの開始を促すテキストを表示
ゲーム開始前、プレイヤーにEnterキーの入力を促すためのテキストを表示します。
- シーンに新しくCanvasを作成
- Canvas内に「PanelCenter」という名前でPannelを作成
- PanelにアタッチされたImageのColorを(R=0, G=0, B=0, A=140)に変更
- PanelのRaycastTargetを外し、ポジションを以下のように設定
- PanelCenterの子要素に新しいTextを作成
- TextのColorを(R=255, G=255, B=255, A=255)に変更
- Textの赤枠部分とポジション以下のように設定
Press the Enter key !
- PanelCenterを非アクティブにして見えない状態に設定
- UiManagerに対応するコードを追加
/// <summary>
/// ゲーム起動のタイミングで必要なUIを表示したりtweenアニメーションを開始する
/// </summary>
public void LoadUi()
{
mCenterPanel.gameObject.SetActive(true);
}
//-------------------
// センターテキスト //
//---------------------------------------------------------------------------------
[SerializeField]
private Image mCenterPanel; ← PanelCenterを指定
[SerializeField]
private Text mCenterText; ← PanelCenter/Textを指定
public void HideCenterMsg()
{
mCenterPanel.gameObject.SetActive(false);
}
- SceneMainを修正
void Update()
{
CheckBackspaceInput();
switch (mState)
{
// ステージの生成
case STATE.LOAD_STAGE:
mGame.StageManager.LoadStage(1);
追加 mGame.UiManager.LoadUi();
mState = STATE.WAIT_ENTER_KEY;
break;
// Enter入力でゲームを開始
case STATE.WAIT_ENTER_KEY:
if (WaitEnter())
{
追加 mGame.UiManager.HideCenterMsg();
mGame.StageManager.StartGame();
mState = STATE.PLAY;
}
break;
// プレイ中
case STATE.PLAY:
if (mGame.IsGameOver)
{
mState = STATE.GAME_OVER;
}
break;
}
}
プロジェクトを実行するとキー入力を促すメッセージが表示され、Enterキーを押してゲームが開始されるタイミングでメッセージが非表示になります。
#DOTweenでUIにアニメーションを設定する
続いて、先ほど作成したテキストにtweenアニメーションを設定します。
【tweenアニメーション(トゥイーンアニメーション)】
Between(~の間)から由来しているアニメーション手法の1つで、オブジェクトの
大きさ・移動量・角度など数値で表現できるパラメーターの最初と終わりの値を指定し、
その間を補間することでアニメーションを表現する方法。
このときに中間部分の動きを自動計算して補間してくれるシステムをTweenエンジンと呼ぶ。
DOTweetはUnityで(多分)最も多くの開発者が利用するTweenエンジンの1つ。
尚、ドット絵など複数の画像をパラパラ漫画のように切り替えてアニメーションを表現する
手法は「フレームアニメーション」と呼ばれる。
###DOTweenのセットアップ
DOTweenはインポートとは別に、現在使っているUnityのversionに合わせたセットアップをしなければプロジェクトで利用することができません。
セットアップと言っても何ら難しいことはなく、3クリックで完了します。
- ウィンドウメニューの「Tools」を選択
- 続けて「Demigiant → DOTween Unity Panel」を選択
- 新しく開いた設定パネルからSetupDotweenをクリック
真ん中やや上の「DOTWEEN SETUP REQUIRED」の文字が消えれば完了です。
###Tweenアニメーションを開始する
では、UiManagerを修正して中央のテキストにTweenアニメーションを設定していきます。
追加 using DG.Tweening;
public void LoadUi()
{
mCenterPanel.gameObject.SetActive(true);
追加 mCenterText.DOFade(0.1f, 1.2f).SetEase(Ease.InCubic).SetLoops(-1, LoopType.Yoyo);
}
LoadUi()に中央テキストのアルファ値を操作した点滅するTweenアニメーションの設定を追加しました。
こちらについては上記の記事が大変わかりやすく解説されていますので、ご紹介させていただきます。
プロジェクトを実行すると画面センターのメッセージが点滅することが確認できます。
###注意:Tweenアニメーションの終了
一度開始したTweenアニメーションは適用されているオブジェクトのアクティブ状態にかかわらず、Killするまで停止されません。
Enterキーの入力を受け付けるとUiManager#HideCenterMsg()によって中央のメッセージは非アクティブな(見えない)状態となりますが、mCenterTextに設定しているTweenアニメーションはそのまま動作し続けます。
この問題を解消するために、メッセージを非表示にすると同時にTweenアニメーションを終了します。
public void HideCenterMsg()
{
mCenterPanel.gameObject.SetActive(false);
追加 mCenterText.DOKill(false);
}
これによってUiにTweenアニメーション開始から終了までを実装することができました。
今回のフェード処理以外にもDOTWeenには様々なメソッドが定義されています。
ちなみに……
Tweenエンジンなしで今回のフェード処理(に近いモノ)を実装する場合は恐らく以下のようなかんじになります。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class FlashText : MonoBehaviour {
private Text mText;
private bool mIsActive;
private int mState;
private float mAlpha;
private float mWait;
private float mMinAlpha;
private float mMaxAlpha;
private float mValueAlpha;
private float mTopWait;
void Start () {
mText = GetComponent<Text>();
}
public void StartFlash(float startAlpha, float minAlpha, float maxAlpha, float seconds, float topWait)
{
mState = 0;
mWait = 0.0f;
mAlpha = startAlpha;
mMinAlpha = minAlpha;
mMaxAlpha = maxAlpha;
mValueAlpha = (mMaxAlpha - mMinAlpha) / seconds;
mTopWait = topWait;
mIsActive = true;
}
public void StopFlash()
{
mIsActive = false;
}
void Update () {
if (!mIsActive) return;
switch (mState)
{
case 0: // フェードアウト開始まで待機
mWait += Time.deltaTime;
if (mWait >= mTopWait) mState = 1;
break;
case 1: // フェードアウト
mAlpha -= mValueAlpha * Time.deltaTime;
if (mAlpha <= mMinAlpha)
{
mAlpha = mMinAlpha;
mText.color = new Color(1.0f, 1.0f, 1.0f, mAlpha);
mState = 2;
}
else
{
mText.color = new Color(1.0f, 1.0f, 1.0f, mAlpha);
}
break;
case 2: // フェードイン
mAlpha += mValueAlpha * Time.deltaTime;
if (mAlpha >= mMaxAlpha)
{
mAlpha = mMaxAlpha;
mText.color = new Color(1.0f, 1.0f, 1.0f, mAlpha);
mWait = 0;
mState = 0;
}
else
{
mText.color = new Color(1.0f, 1.0f, 1.0f, mAlpha);
}
break;
}
}
}
点滅させるオブジェクトにアタッチされたFlashTextに対してStartFlash()を実行する
targetText.GetComponent<FlashText>().StartFlash(1.0f, 0.1f, 1.0f, 1.2f, 1.0f);
DOTweenを使えばこういった専用のクラスを一から作ることなく、より複雑なTweenアニメーションを簡単に実装することができます。
この作品はユニティちゃんライセンス条項の元に提供されています