実現したいこと
タイトルシーンのヒエラルキーにある画面内に配置されたボタンをクリックしたらフェードインして、非同期で処理(SceneManager.LoadSceneAsync)、プログレスバーが100%に到達したらフェードアウトして、inspector内のボタンのOnClickにアタッチしたLoadScene関数内のシーン名に遷移する。
前提
こちらのサイトを参考に非同期処理のシーン読み込み(遷移)とフェードイン・アウトを実装したいのですがうまくいきません。
発生している問題・エラーメッセージ
ボタンをクリックしたらフェード処理を実行するのですが、ボタンをクリックする前にフェード処理が行われてしまってしまいます。
またこのようなエラーメッセージが現れます。(実行はできます。)
UnityException: Transform child out of bounds LevelLoader.Start () (at Assets/Scripts/LevelLoader.cs:38)
実行するとこのようなエラーが現れます。
NullReferenceException: Object reference not set to an instance of an object LevelLoader+<LoadAsync>d__13.MoveNext () (at Assets/Scripts/LevelLoader.cs:75) UnityEngine.SetupCoroutine.InvokeMoveNext (System.Collections.IEnumerator enumerator, System.IntPtr returnValueAddress) (at <f1212ad1dec44ce7b7147976b91869c3>:0) UnityEngine.MonoBehaviour:StartCoroutine(IEnumerator) <LoadLevel>d__12:MoveNext() (at Assets/Scripts/LevelLoader.cs:66) UnityEngine.SetupCoroutine:InvokeMoveNext(IEnumerator, IntPtr)
ボタンをクリックしたらシーン遷移は実行できるのですがフェード処理ができません。(フェード処理が終わった後にボタンをクリックするとシーン遷移は実行できます。)
補足
ヒエラルキーの配置です。
実行画面です。(エラー解消後の挙動)
ボタンのコンポーネントです。
Animatorのセッティング
フェード用の黒いImage
該当のソースコード
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(string sceneName) { StartCoroutine(LoadLevel(sceneName)); } // シーンリロートしたい時この関数を使う public void ReloadScene(string sceneName) { var acrtivesceneindex = SceneManager.GetActiveScene().buildIndex; StartCoroutine(LoadLevel(sceneName)); } // 内部用ロードコルーチン private IEnumerator LoadLevel(string sceneName) { // 遅延 yield return new WaitForSeconds(DelayActiveTime); // フェードアウトスタート transition.SetTrigger("Start"); // 待ち yield return new WaitForSeconds(transitionTime); // ロード開始 StartCoroutine(LoadAsync(sceneName)); } // 非同期ロード処理 private IEnumerator LoadAsync(string sceneName) { LoadOperation = SceneManager.LoadSceneAsync(sceneName); 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; } } } }
試したこと
このサイト内のプログラムをコピペしてLoadScene関連の引数をstringに変更してシーン名でシーン遷移できるようにしています。
バージョン
Unity2021.3.4f1
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2024/01/16 17:18
2024/01/16 17:26
2024/01/17 01:16
2024/01/17 06:19
2024/01/17 08:54
2024/01/17 09:34
2024/01/17 13:22
2024/01/18 02:37
2024/01/18 04:33
2024/01/18 04:54