この記事は「Unityアセット冬のアドベントカレンダー 2019 Winter!」の20日目の記事です。
http://assetstore.info/asset-advent-calendar-2019-winter/
ゲームUI
みなさん、ゲームUIにはこだわっていますか?
ゲームエンジニアの中には、あまり興味がない/こだわらないような人もいるのではないでしょうか。
しかし、ゲームのUIというのはユーザーが直接触る部分であり、UIが魅力的でないと折角ゲームの内容が面白くても伝わりづらくなってしまいます。
今回は、DOTweenというUnityの無料アセット(有料版あり)を使って、簡単に魅力的なUIを作る具体例を記事にしました。
DOTweenという神アセット
DOTweenは簡単にいうと、オブジェクトやUIのアニメーションを簡単に実装できる、いわゆる「Tween系」アセットです。
DOTween(無料版)のアセットストアリンクはこちら
DOTween Pro(有料版)のアセットストアリンクはこちら
transform.DOScale(0f, 1f);
こんな感じで記述するだけで、対象のtransformのscaleを現在の値から0fまで、1f秒間かけてアニメーションするようになります。
処理時間もかなり早いらしい(?)
さらにDOTweenの便利なところは、
「大きさを変えてから移動させて、フェードアウトさせる」のように一連のアニメーションの流れを(一行で)簡単に記述することができたり、
「このアニメーションが終わったらこのメソッドを実行する」のようなイベント実行もできたり、
「このIDが付けられたアニメーションを一斉に開始する」ことができたり、
控えめにいっても神アセットです。
ちなみに無料版と有料版(Pro)の違いは、有料版だと
- コードを書かなくてもインスペクタからアニメーションを設定できる
- インスペクタから設定したアニメーションはエディタ実行しなくてもプレビューで確認できる
- 移動アニメーションさせるルートをパスで操作できる
などの追加機能が使えます。
もちろん無料版で使える機能も全て使えます。
特に上2つの機能はかなり便利なので、有料版を購入する価値は十分にあると思います。
魅力的なゲームUIとは
個人的には、ゲームのUI(ゲームに限らずですが)で必須なことは
- 押すべきボタン(見るべき部分)がすぐ分かること
- 押したいボタン(見たい部分)がすぐ分かること
- 押したことが分かること(フィードバック)
だと思っています。
近接/整列の要因とか、同じ機能のものはデザインを統一させるとか、コントラストをつけるとかいろいろ技法はありますが、その技法を使って達成したい目的は主に上の3つなのかな、と。
加えて、魅力的ポイントとして
「静的なUIをできる限り作らない」
だと思います。
特にゲームでは「楽しむ」ということが目的なので、「退屈させない」ためにも動きが全くない画面というのはあまりよくないと思っています。
DOTweenで作ってみた
さて、前置きが長くなってしまいましたが、実際にDOTweenを使って「魅力的なUI」を作ってみました。
ボタン押下アニメーション
まずはボタンを押下した際のアニメーション。
Unityのデフォルトのボタンでは、押している間に若干色が暗くなるアニメーションがされています。
しかし、これだとほとんど気づかないですし押している感もありません。
「ボタンアニメーションを変更する」ことはUnity初心者脱却の一歩ではないでしょうか。(個人的意見)
こちらがデフォルトのボタンアニメーション。
押したことに対するフィードバックが少ないですよね。
押してすぐに何か変化があるならまだマシですが、押したらシーンをロード、とかの処理だと少しラグがあるのでユーザーは「押せたかな?」とストレスを感じてしまいます。
続いて、DOTweenを利用したボタンアニメーション。
押したことがはっきり分かりますよね。
しかもアニメーションが気持ちよく、押したくなってしまいます。
ボタンが押したくなるということは、ゲームの継続にも繋がるわけです。
このボタンは以下のスクリプトで実装されています。
using UnityEngine;
using UnityEngine.UI;
using DG.Tweening;
public class ButtonController : MonoBehaviour
{
void Awake()
{
Button button = GetComponent<Button>();
button.onClick.AddListener(OnClick);
}
void OnClick()
{
transform.DOScale(1.1f, 0.5f).SetEase(Ease.OutElastic);
GetComponentInChildren<Text>().text = "押された";
}
}
まずDOTweenを使う時は
using DG.Tweening;
を忘れずに書きましょう。
そして、ボタンが押された時に
transform.DOScale(1.1f, 0.5f).SetEase(Ease.OutElastic);
という処理をしています。
これは、「transformのscaleの値を1.1fに、0.5秒間でしてね。補間方法はOutElasticで。」という処理です。
ポップなボタンの押下アニメーションだと、OutElasticが一番気持ちいいかな、と個人的には思います。
ボタンの強調アニメーション
次に、ボタンの強調アニメーションについてです。
ひとつの画面にボタンが複数存在する場合、「押して欲しいボタン」を強調することが大事です。
「押して欲しいボタン」とは、例えばタイトル画面でいうと「Playボタン」のようなもの。
たまにしか押さないボタンである「ランキングボタン」「設定ボタン」のようなものよりも、押して欲しい「Playボタン」を強調すべきです。
タイトル画面以外の例だと、リザルト画面の「リトライ」とか、設定画面の「決定」とか。
押して欲しいボタンを強調できていない例がこちらです。
ボタンが3つあり、他のボタンに比べて押して欲しいボタンがあるにも関わらず、全く同じ見た目をしています。
よくある例としては、ボタンの大きさを変えて強調する、という手法です。
この方法は頻繁に使われ、かなり効果の高い手法です。
是非とも使うべき。
加えて、今回はDOTweenのアニメーションを使ってさらに強調してみました。
先ほどに比べて、より「押して欲しい」感が伝わってきますよね。
ただここまで強調すると、設定画面の決定ボタンとかだとさすがに鬱陶しいと思うので、用法容量を守ってお使いください、という感じです。
個人的にはカジュアル系ゲームであれば、タイトル画面でのPlayボタンには使いやすいと思います。
スクリプトはこちらです。
using UnityEngine;
using DG.Tweening;
public class ButtonController : MonoBehaviour
{
void Awake()
{
StartStrongButtonAnim();
}
void StartStrongButtonAnim()
{
transform.DOScale(0.1f, 1f)
.SetRelative(true)
.SetEase(Ease.OutQuart)
.SetLoops(-1, LoopType.Restart);
}
}
今回はSetRelative(true)とすることで、相対的に0.1f拡大しています。
補間には「Ease.OutQuart」を指定。
そして、このアニメーションはループさせる必要があるため、SetLoops()を用いてループの設定をしています。
第一引数の「-1」というのはループさせる回数で、-1を指定することで無限ループになります。
第二引数ではループの仕方をしていすることができます。
アニメーションが「0」の状態から「1」の状態に向かうとすると、
LoopType.Restartは「0→1」「0→1」「0→1」のようにアニメーションが終了すると最初からまた始める、というもの。
LoopType.Yoyoは「0→1」「1→0」「0→1」のようにアニメーションが終了すると逆再生で元に戻る、というもの。
LoopType.Incrementalは「0→1」「1→2」「2→3」のようにアニメーション終了時点を「0」として再度「0→1」のアニメーションを開始する、というもの。
今回はLoopType.Restartを指定。
ウィンドウ表示アニメーション
続いて、リザルト画面などのウィンドウの表示アニメーションです。
突然ウィンドウが出てくると、ユーザーは「!?」となってしまう場合があります。
ちなみに小さい子どもは、ウィンドウの表示を見た時に「前面にウィンドウが覆いかぶさっている」という状態をうまく認識できないのだとか。(どっかで聞いただけなので信憑性はありません)
「元のゲーム画面の前面に、新たなウィンドウが表示されている」ということを分かりやすく伝えることが、快適さ、分かりやすさにつながります。
そこで、DOTweenを使ってウィンドウの表示アニメーションを作成してみました。
まずはこちら。
先ほどのボタン押下アニメーションと同様、scaleの値をアニメーションさせたものです。
スクリプトはこちら。
using UnityEngine;
using DG.Tweening;
public class ButtonController : MonoBehaviour
{
void Awake()
{
transform.localScale = Vector3.zero;
ShowWindow();
}
void ShowWindow()
{
transform.DOScale(1f, 1f).SetEase(Ease.OutBounce);
}
}
先ほどのボタン押下アニメーションでは「Ease.OutElastic」を指定していましたが、今回は「Ease.OutBounce」を指定しました。
ほかにも、垂直方向の座標をアニメーションさせたパターンも。
スクリプトはこちら。
using UnityEngine;
using DG.Tweening;
public class ButtonController : MonoBehaviour
{
RectTransform rectTransform;
void Awake()
{
rectTransform = GetComponent();
rectTransform.anchoredPosition = new Vector3(0, 700, 0);
ShowWindow();
}
void ShowWindow()
{
rectTransform.DOLocalMoveY(0f, 1f).SetEase(Ease.OutBounce);
}
}
これも「Ease.OutBounce」を使っています。
また、UI要素の移動なので、Transform型ではなくRectTransform型を使用しています。
NEW RECORDアニメーション
最後に、リザルト画面でベストスコアを出した場合の、「NEW RECORD!」と表示する際のアニメーションです。
普通に静止画で表示するとこのようになります。
せっかくベストスコアを更新したわけですから、ユーザーをもっと嬉しくさせるようなアニメーションを追加するべきです。
ということで、DOTweenを用いて作成したのがこちら。
スクリプトはこちらです。
using UnityEngine;
using DG.Tweening;
public class ButtonController : MonoBehaviour
{
RectTransform rectTransform;
void Awake()
{
rectTransform = GetComponent();
StartNewRecordAnim();
}
void StartNewRecordAnim()
{
rectTransform.DOLocalMoveY(20f, 0.4f)
.SetRelative(true)
.SetEase(Ease.OutQuad)
.SetLoops(-1, LoopType.Yoyo);
}
}
飛び跳ねるようなアニメーションを追加したことで、よりユーザーに嬉しさを感じてもらえるようになると思います。
今回もRectTransform型についてアニメーション。
SetRelative(true)を指定しておきます。
(これが無いと絶対座標の20fの位置まで移動してしまいます)
また、イージング(補間)方法は「Ease.OutQuad」を使用しました。
無限ループを指定し、ループタイプにはLoopType.Yoyoを指定しました。
まとめ
以上、DOTweenを使った魅了的なゲームUIアニメーションの作りかたでした。
これまで紹介したものは全て無料版/有料版問わず実装することができます。
ただ、有料版だとこんな感じでコンポーネントをアタッチすればインスペクタで動作を指定、そしてプレビューができます。
このプレビュー機能がなかなか便利で、いちいちエディタ実行しなくても簡単に動作確認ができるので助かっています。
DOTweenを使って簡単にUIアニメーションを作りましょう!