読者です 読者をやめる 読者になる 読者になる

【Unity】 uGUIについて

unity UnityAdventCalendar2016

はじめに

はじめまして。 カヤックのソーシャルゲーム事業部の Unity エンジニアのです。
今回は Unity の uGUI について紹介します。
この記事はカヤック Unity アドベントカレンダー 2016 の 12 日目の記事です。

uGUI について

Unity 4.6 から新しい UI システム uGUI が搭載されるようになって、Unity 5 では uGUI がさらに更新され、とても便利なツールになりました。
昔は NGUI を使ってたかもしれませんが、新しいプロジェクトではオフィシャルな uGUI を使うのは良いでしょう。

全体像

uGUI では以下の構造になっています。

  • Canvas:子にUI要素(画像やボタンとか)を持つ
  • EventSystem:マウス操作、タッチ操作、キーボード操作などから発生するイベント処理を担当する

各 UI コンポーネントの紹介について、Unity - Manual: UI を見ながら、Unity 上で試してみるとすぐにわかると思います。

レンダリング

GUI とはいえ、実装上で注意しないと Batch 数が増え、ゲームが重くなるので、レンダリングのチューニングがとても重要になっています。

テクスチャの設定

Packing Tag

Sprite ごとに Packing Tag が設定でき、同じ文字列に設定された Sprite が自動的に一つのテクスチャにパックされます。
これにより、同じ Packing Tag の画像を連続で描画する時に、GPU の Render State の切り替えをしなくていいので、一回で描画できて、レンダリングが速くなります。

Packing Tag は場合によって慎重に設定することが大事です。
例えば:

  1. LayerA: PackA
  2. LayerB: PackB
  3. LayerC: PackA

の場合に、LayerB が LayerA と LayerC に被るエリアがあったら、描画時に Batch できないため、合計 3 回レンダリングする必要があるのです。
LayerB の Packing Tag を PackA に設定すると、全部 Batch できるので、1 回でレンダリング出来ます。

その他注意すべきこと:

  • Resources.Load 系のメソッドで動的にロードされた Sprite は、事前に Packing Tag を設定しても効かないので、この場合は Sprite Sheet などを使うのをオススメです。
  • フォントを使う文字は別テクスチャになるので、普通の画像と Batch できません。
  • Image の Color の Alpha を 0 に設定しても、レンダリングされて無駄な描画負荷になってしまうので、隠したい場合は Disable にするのがオススメです。
  • Image の Sprite を設定しないなら、デフォルトの空画像が使われます。これのせいで Batch 数が増えるかもしれません。

Generate Mip Maps

この設定は同じ画像の低い解像度のバージョンを自動で生成するという意味です。3D のシーンでは Sprite が遠い場所にあったら自動的に低い解像度の画像を使う場合が多いが、GUI の場合はほとんど使われないです。
この設定をオンにすると、無駄な Sprite パックが生成されるから、使わないときはオフにするのを忘れないようにしましょう。

Sprite Packer

パッケージされた Sprite を確認したり、ポリシーを変えてリパックしたりする便利ツールです。
Unity - Manual: Sprite Packer
使う前にドキュメントをチェックしてみましょう。

画像ファイルが実機のメモリで展開されるときに、サイズが 2 の整数乗になるので、パッケージされた画像も全部 256, 512, 1024 などのサイズになっています。

Auto Layout

オブジェクトをグループで表示したい場合によく使うコンポーネント集。位置、サイズ調整が自動でやってくれるなど、是非活用してみてください。
Unity - Manual: Auto Layout

スクロールビュー

uGUI では簡単にスクロールビューが作れます。Auto Layout と合わせて使うと、ダイナミックな表現もできて、とても楽なのです。
スクロールビューの使い方はドキュメントを見るといいでしょう。
Unity - Manual: Scroll Rect

イベントシステム

EventTrigger

UI エレメントでマウスダウンやクリックなどのイベントをつけたい場合はよくあると思います。 この時は EventSystems のインターフェースを実装するのがいいです。

using UnityEngine;
using UnityEngine.EventSystems;

public class EventTriggerExample : IPointerDownHandler
{
    public void OnPointerDown(PointerEventData data)
    {
        Debug.Log( "OnPointerDown called." );
    }
}

既存のイベントはここに参考しましょう:
Unity - Scripting API: EventTrigger

IEventSystemHandler

時にはカスタムなイベントを作りたいかもしれないですね。この場合は IEventSystemHandler を使いましょう。

using UnityEngine;
using UnityEngine.EventSystems;

public interface ICustomEventHandler : IEventSystemHandler
{
    void OnCustomEvent();
}

public class Example
{
    private static void InvokeOnCustomEvent(ICustomEventHandler target, BaseEventData data)
    {
        target.OnCustomEvent();
    }

    private void Execute(GameObject target)
    {
        ExecuteEvents.Execute<ICustomEventHandler>(target, null, InvokeOnCustomEvent);
    }
}

その他

uGUI はオープンソースになっています。
ハマったり、深く勉強したかったり、拡張したかったりする場合は、ソースを見るのがオススメです。リポジトリはこちら:
Unity-Technologies / UI - Bitbucket