📗

【Unity】FadeCamera2を使用したフェードをUniTaskで実装

2024/08/29に公開

はじめに

初めての方も、そうでない方もこんにちは!
現役ゲームプログラマーのたむぼーです。
自己紹介を載せているので、気になる方は見ていただければ嬉しいです!

今回は
 FadeCamera2を使用したフェードをUniTaskで実装
したので紹介します

https://zenn.dev/tmb/articles/1072f8ea010299

FadeCamera2について

GitHubからFadeCamera2.unitypackageをDLし、Unityにインポートします。

https://github.com/tsubaki/FadeCamera2/tree/master

ルール画像の用意

フェードに使用するルール画像を用意してください。
今回は下記サイトで配布してくださっているものを使用します

https://4you.bz/rule

準備

ルール画像をUnityにインポートしたら、設定を画像の赤線のようにしてください。

FadeCamera2.unitypackageをインポートしたら、Fadeフォルダが追加されるので
その内のFadeCanvas.prefabを編集します

FadeCanvas.prefabをダブルクリックして編集モードにします
・MaskTextureにルール画像を設定
・今回作成するTransition.csをアタッチし、FadeImageを渡す

FadeCanvas.prefabをシーンに配置する(DontDestroyOnLoadするため、一番初めに読み込まれるシーンに配置する)

使い方

private async UniTaskVoid ExampleFade()
{
    // フェードアウト開始
    await Utils.Transition.Instance.FadeOutAsync(
        1.0f,                           // フェードの間隔
        () => { Debug.Log("開始"); },   // フェードアウト開始時に実行するアクション
        () => { Debug.Log("終了"); },   // フェードアウト終了時に実行するアクション
        Color.red                       // フェード色
    );

    // フェード中に行いたい処理

    // フェードイン開始
    await Utils.Transition.Instance.FadeInAsync(
        1.0f,                           // フェードの間隔
        () => { Debug.Log("開始"); },   // フェードイン開始時に実行するアクション
        () => { Debug.Log("終了"); }    // フェードイン終了時に実行するアクション
    );
}

スクリプト

Transition.cs
using System;
using UnityEngine;
using Cysharp.Threading.Tasks;

namespace Utils
{
    public class Transition : MonoBehaviour
    {
        static public Transition Instance { get; private set; }

        [SerializeField]
        private FadeImage _fadeImage;

        /// <summary> トランジション中か </summary>
        public bool IsTransition { get; private set; }

        readonly private float FadeOutEndValue = 1.0f;
        readonly private float FadeInEndValue = 0.0f;

        /// <summary>
        /// 開始時
        /// </summary>
        private void Awake()
        {
            if (Instance != null && Instance != this)
            {
                Destroy(gameObject);
                return;
            }
            Instance = this;
            DontDestroyOnLoad(gameObject);
        }

        /// <summary>
        /// フェード値を設定
        /// </summary>
        public void SetFadeValue(float fadeValue, Color? color = null)
        {
            // 色を設定
            if (color.HasValue)
            {
                _fadeImage.SetColor(color.Value);
            }

            _fadeImage.Range = fadeValue;
        }

        /// <summary>
        /// フェードアウトを開始
        /// </summary>
        public async UniTask FadeOutAsync(float duration = 1.0f, Action onFadeOutStart = null, Action onFadeOutEnd = null, Color? color = null)
        {
            await FadeAsync(duration, FadeOutEndValue, onFadeOutStart, onFadeOutEnd, color);
        }

        /// <summary>
        /// フェードインを開始
        /// </summary>
        public async UniTask FadeInAsync(float duration = 1.0f, Action onFadeInStart = null, Action onFadeInEnd = null)
        {
            await FadeAsync(duration, FadeInEndValue, onFadeInStart, onFadeInEnd, null);
        }

        /// <summary>
        /// フェード
        /// </summary>
        private async UniTask FadeAsync(float duration, float endValue, Action onFadeStart, Action onFadeEnd, Color? color)
        {
            if (endValue == FadeOutEndValue)
            {
                IsTransition = true;

                // 色を設定
                if (color.HasValue)
                {
                    _fadeImage.SetColor(color.Value);
                }
            }

            // 開始前アクション
            onFadeStart?.Invoke();
            onFadeStart = null;

            float startRange = _fadeImage.Range;
            float elapsedTime = 0f;

            while (elapsedTime < duration)
            {
                elapsedTime += Time.deltaTime;
                _fadeImage.Range = Mathf.Lerp(startRange, endValue, elapsedTime / duration);
                await UniTask.Yield();
            }

            _fadeImage.Range = endValue;

            if (endValue == FadeInEndValue)
            {
                IsTransition = false;
                _fadeImage.ResetColor();
            }

            // 終了後アクション
            onFadeEnd?.Invoke();
            onFadeEnd = null;
        }
    }
}

Discussion