ハトネコエ Web がくしゅうちょう

プログラミングやサーバー関連、チームマネジメントなど得た技術のまとめ

Unity の uGUI でウィンドウのフェードアウト処理

ゲームを作るなら細かい演出は大事! フェードアウトは大事!

Unity で、GameObject のフェードアウト処理をおこないたくてネットで探したんですが、
GameObject 単体のフェードアウト処理になっているものが多かったので、
All Children GameObject (すべての子オブジェクト)に対しても同時におこなえるフェードアウト処理をおこなう方法について書きます!

なお、シーン間のフェードアウト・イン処理をおこなう方法としては、
こちらの 『Simple Fade Scene Transition System』 というアセットがおすすめです。
今回のコードを書くにあたって参考にした部分が多いです。

ポイント1: CanvasGroup

こちらの Q&A が参考になりました。 : How to fade a game object will all its children?

GameObject の Image に対して処理をおこなう方法ですと、
子オブジェクトのアルファ値はそのままになってしまいます。

Canvas Group を目的の GameObject にコンポーネントとして付与することで、
Children GameObject を含めたアルファ値の操作を楽におこなうことが出来ます。

f:id:nekonenene:20190519180615p:plain
Canvas Group Component は Alpha を値として持つ

ポイント2: EventSystem

また、フェードアウト中はユーザーの操作を受け付けたくありません。

タッチ操作やクリック操作を無効にする必要があります。
そのためには、操作の受け付け担当である EventSystem さんを一時的に無効にしてあげるのが一番です。

EventSystem eventSystem = GameObject.FindObjectOfType<EventSystem>();
eventSystem.enabled = false;

でおこなえます。true に戻してあげるのを忘れないよう注意しましょう!

(参考: UnityのEventSystemを操る - あさちゅんのゲームブログ

そして出来上がったコード

出来上がったコードがこちらです。

対象の GameObject に、独自 Component である Fadeout Component と、前述した CanvasGroup Component を一時的にアタッチし、
フェードアウトが終わったら削除し、 GameObject に対して SetActive(false) を実行しています。

Destroy(this); のあとのコードが実行されるのが自分的には不思議なんですが、ここなんでなのでしょう……わかる方いらっしゃいましたら教えてください)

なお、独自 Component を作ってアタッチしているのは、 StartCoroutine メソッドなどの実行に Context (現在の状態)を渡す必要があるからです。
(参考: coroutineとasync/awaitのあれこれ
もちろん、 new GameObject(); で GameObject を作って、そこに Fadeout Component をアタッチするという方法でも可能です。

呼び出し側のコード

呼び出し側は以下のようなコードです。
ブログ用にいろいろ省略していますが、 OnClickCloseButton メソッドを Button の OnClick 用のメソッドとして使い、
OpenSettingsWindow メソッドや CloseSettingsWindow は別クラスから呼び出されることもあります。

using UnityEngine;
using Util;

public class SettingsWindowController : MonoBehaviour {
    GameObject settingsWindowPanel;

    void Start() {
        settingsWindowPanel = this.gameObject;
        settingsWindowPanel.SetActive(false);
    }

    public void OpenSettingsWindow() {
        settingsWindowPanel.SetActive(true);
    }

    public void OnClickCloseButton() {
        CloseSettingsWindow();
    }

    public void CloseSettingsWindow() {
        Fade.FadeoutObject(settingsWindowPanel, 0.3f);
    }
}

できあがり

無事に、ウィンドウやその中のテキストなどがいっしょにフェードアウトしてくれました!

f:id:nekonenene:20190519184434g:plain
Fade out the window on close

きっと似たようなコードでフェードイン処理も作れる気がするので、
次はフェードイン処理も作っておきたいな、と思いました。

この記事が Unity を使っている方のお役に立てましたら幸いです。