ほぼDoTweenで作りました。
シーンをまたいで保持されるシングルトンである必要があったので、SingletonMonoBehaviourは下記のものを使わせていただきました。
https://qiita.com/valbeat/items/4b0175755b0cc47d4f6e
using System.Collections;
using System.Collections.Generic;
using DG.Tweening;
using ProjectLabyrinth.Utilities.Inputs;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
namespace ProjectLabyrinth.Main.FadeSystem
{
public class FadeSceneManager : SingletonMonoBehaviour<FadeSceneManager>
{
private CanvasGroup fadeCanvas;
private static float expectedfadetime;
//シーン遷移にかかると予想される時間
public static float expectedFadetime
{
get { return expectedfadetime; }
}
// Use this for initialization
void Awake()
{
var prefab = (GameObject)Resources.Load("FadeCanvas");
var instance = Instantiate(prefab);
fadeCanvas = instance.GetComponent<CanvasGroup>();
DontDestroyOnLoad(fadeCanvas);
DontDestroyOnLoad(fadeCanvas.GetComponentInChildren<Image>());
//http://nn-hokuson.hatenablog.com/entry/2017/05/29/204702
SceneManager.activeSceneChanged += OnActiveSceneChanged;
}
private Sequence sequence;
public void ChangeSceneWithFade(float fadeiotime, float fadewaittime, string nextscenename)
{
var operation = SceneManager.LoadSceneAsync(nextscenename); //次シーンの読み込み開始
operation.allowSceneActivation = false;//シーンの変更をブロック
expectedfadetime = fadeiotime + fadewaittime;
sequence = DOTween.Sequence();
sequence
//.OnStart(InputManager.Instance.StopInput) //入力停止
.Append(fadeCanvas.DOFade(1f, fadeiotime)) //フェードアウト
.AppendCallback(() =>
{
sequence.Pause(); //シーンが変わるまで停止
operation.allowSceneActivation = true; //シーンの変更を許可
})
.AppendInterval(fadewaittime) //暗転中に停止
.Append(fadeCanvas.DOFade(0f, fadeiotime)) //フェードイン
//.OnComplete(InputManager.Instance.StartInput); //入力再開
sequence.Play();
}
void OnActiveSceneChanged(Scene prevScene, Scene nextScene)
{
sequence.Play();
}
}
}
使用例
FadeSceneManager.Instance.ChangeSceneWithFade(1f, 0f, "Stage1");
軽く解説
黒い画像の設定例ですがこんな感じです。Hierarchyで右クリックしてUI→Imageで追加できます。フェードが画面全体にかかるように、RectTransformの位置指定方法の設定を変えるのを忘れないようにしてください。
この画像は透明度を最大にしておきます。
var prefab = (GameObject)Resources.Load("FadeCanvas");
で、画面を黒く覆うUIのPrefabを呼び出して実体化しています。スクリプトからPrefabを作る方法はここを参考にしました。
https://qiita.com/2dgames_jp/items/8a28fd9cf625681faf87
Sequence最初と最後の
OnStart(InputManager.Instance.StopInput)
OnComplete(InputManager.Instance.StartInput)
の2つですが、これは自作のInputManagerの入力を停止する関数です。フェードの開始・終了などはこのような呼び出し方でタイミングを合わせられるので参考にしてください。
ChangeSceneWithFadeの引数は
fadeiotime: フェードにかかる時間
fadewaittime: シーン切り替え完了後、暗転したまま追加で待機する時間
nextscenename: 次のシーンの名前
です。
ChangeSceneWithFadeの中では、アルファ値を変化させて処理しています。
AppendCallbackで自分自身を停止させています。
.AppendCallback(() =>
{
sequence.Pause(); //シーンが変わるまで停止
operation.allowSceneActivation = true; //シーンの変更を許可
})
これによって、暗転が完了したらシーンがロードされて切り替わるまで真っ黒になったまま停止し、切り替わったタイミングでOnActiveSceneChangedが呼び出されて明転が再開するようになっています。