効果
ゲームの中でよく使っているフェイド付きシーン遷移作りました。効果はこんな感じです!
仕様
仕様はこんな感じです。
- Prefabをシーン内配置したら使える
- 非同期(ロード画面付き)
- フェイドアウト、フェイドイン付き
- 遅延実行、ロード完成の時自動シーン遷移するかどうか指定できる
流れ
1. シーン遷移用のPrefab
シーン遷移本体Prefab
フェードアニメーション (UICanvas、Animatorコンポーネント必要)
フェードアニメーション用画像 (UI Image、画面全体サイズと同じの黒画像、Canvas Groupコンポーネント必要)
ロード画面
プログレスバー (今回はUI Sliderを使った)
プログレス文字 (今回はUI Textを使った)
2. フェイドイン、フェイドアウトアニメーション作る
アニメーションを作る。(Alphaを0から1、Alphaを1から0 2種類作ること)
3. フェードアニメーションをAnimatorコンポーネントつける
Animator内はこんな感じです。
開始後はフェイドインする、StartがTriggerになったらフェイドアウトする。
4.シーン遷移本体Prefabをコード追加
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class LevelLoader : MonoBehaviour
{
// シーン遷移のアニメーション
[Header("シーン遷移アニメーション")]
public Animator transition;
// フェイドアウト開始から実際にシーン遷移開始までの時間
[Header("シーン遷移時間")]
[Range(0.0f,5.0f)]
public float transitionTime = 1f;
// フェイドアウト開始までの遅延時間
[Header("遅延実行")]
[Range(0.0f,5.0f)]
public float DelayActiveTime = 0.5f;
// ロード完成になったらすぐ遷移するかどうか
[Header("ロード完成の時自動シーン遷移")]
public bool TransitionAuto_LoadFinish = false;
// いろいろ
private Canvas loadingcanvas;
private Slider loadingbar;
private Text loadingtext;
// 非同期ロード用
private AsyncOperation LoadOperation;
void Awake()
{
transform.GetChild(0).gameObject.SetActive(true);
}
// Start is called before the first frame update
void Start()
{
// いろいろ代入
loadingcanvas = transform.GetChild(1).gameObject.GetComponent<Canvas>();
loadingbar = loadingcanvas.transform.GetChild(0).GetComponent<Slider>();
loadingtext = loadingcanvas.transform.GetChild(1).GetComponent<Text>();
}
// ほかのシーンロートしたい時この関数を使う(シーンのインデックス)
public void LoadScene(int index)
{
StartCoroutine(LoadLevel(index));
}
// シーンリロートしたい時この関数を使う
public void ReloadScene()
{
var acrtivesceneindex = SceneManager.GetActiveScene().buildIndex;
StartCoroutine(LoadLevel(acrtivesceneindex));
}
// 内部用ロードコルーチン
private IEnumerator LoadLevel(int index)
{
// 遅延
yield return new WaitForSeconds(DelayActiveTime);
// フェードアウトスタート
transition.SetTrigger("Start");
// 待ち
yield return new WaitForSeconds(transitionTime);
// ロード開始
StartCoroutine(LoadAsync(index));
}
// 非同期ロード処理
private IEnumerator LoadAsync(int s_index)
{
LoadOperation = SceneManager.LoadSceneAsync(s_index);
LoadOperation.allowSceneActivation = TransitionAuto_LoadFinish;
// ロード画面表示
loadingcanvas.enabled = true;
while (!LoadOperation.isDone)
{
InLoading();
yield return null;
}
}
// ロード画面内処理
private void InLoading()
{
/*
ロード画面内したい処理ここで書く
*/
// プログレスバーと文字を更新する
float progress = Mathf.Clamp01(LoadOperation.progress / .9f);
loadingbar.value = progress;
loadingtext.text = progress * 100f + " %";
if (!LoadOperation.allowSceneActivation)
{
/*
ロード完成から実際にシーン遷移までの処理ここで書く
(ここはロード完成後スペースキー押したら遷移の処理にします)
*/
if (Input.GetKeyDown(KeyCode.Space))
{
LoadOperation.allowSceneActivation = true;
}
}
}
}