質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity3D

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

Q&A

解決済

1回答

532閲覧

Unityのシーン遷移の不具合を解決したい。

Ace230

総合スコア4

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity3D

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

0グッド

0クリップ

投稿2024/01/16 04:50

編集2024/01/17 06:18

実現したいこと

タイトルシーンのヒエラルキーにある画面内に配置されたボタンをクリックしたらフェードインして、非同期で処理(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

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

エラーを見るとここで失敗しているため、Startメソッドは中断されています。

void Start() { loadingcanvas = transform.GetChild(1).gameObject.GetComponent<Canvas>();

LevelLoaderコンポーネントがボタンについているようですが、
ボタンの子供にはText1つしかいないのではないでしょうか。
そのため、GetChild(1)で1番目の子供を取得しようとしてエラーが出ています。
Canvasが取得できていないため、後のエラーも発生しています。
Canvasを取得できるよう、構造を見直してみてください。


追記

プロジェクトを確認しましたが、Crossfade(AnimatorController)の作りが参考にされたサイトと違います。
イメージ説明

Entry->Crossfade_In->Crossfade_Out
の順で繋いでみてください。
In->Outの間はStartトリガーで遷移するようにします。

投稿2024/01/16 10:20

編集2024/01/18 04:32
Ratnaraj

総合スコア120

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Ace230

2024/01/16 17:18

回答ありがとうございます。 ご指摘していただいた通りボタンのインスペクター周りなどを見直して、エラーなどが解消できたのですが、 フェード処理がうまくできません。 具体的には参考にしたサイト内ののようなフェードアウトした後にプログレスバーを表示して読み込み、フェードインしたら次のシーンに切り替わってるような処理です。
Ace230

2024/01/16 17:26

すみませんトランジションでした。
Ratnaraj

2024/01/17 01:16

修正された後の挙動を確認したいので、 追加で動画をあげていただけますか?
Ace230

2024/01/17 06:19

修正後の動画を投稿しました。
Ratnaraj

2024/01/17 08:54

想像になってしまいますが、 // ロード画面表示 loadingcanvas.enabled = true; のタイミングでスライダー等が表示されるべきなのだと思うので、 開始時にはインスペクタ上でCanvasのチェックボックスのチェックを外しておく必要がありそうです。 修正後の動画を見ましたが、フェードアウトした後即シーン遷移しているように見えます。 これはLevelLoaderコンポーネントとフェード用のImage等が、タイトルシーン上にあるため、 シーン遷移時にシーンごと破棄されているためかと思います。 参考にされたサイトの冒頭の動画を見るとシーン遷移後にフェードイン出来ているようですが、 そうはならないような気がするのですが・・・。 (フェードイン前にスライダーが消えてますが、スクリプト上そんなことしてなさそうなんですよね) 一度LevelLoader.Awakeの中で、 DontDestroyOnLoad(this); を追加して実行してもらえますか?
Ace230

2024/01/17 09:34

>一度LevelLoader.Awakeの中で、DontDestroyOnLoad(this);を追加して実行してもらえますか? 提示していただいたコードをプログラム内に書き込みましたが結果はほとんど変わりませんでした。。。 >開始時にはインスペクタ上でCanvasのチェックボックスのチェックを外しておく必要がありそうです。 loadingbar.gameObject.SetActive(true)で一度プログレスバーの描画を制御してしたので、気が付きませんでした。
Ratnaraj

2024/01/17 13:22

すみません。 DontDestroyOnLoad(this); は外してください。 同じ環境を作って確認してみました。 おそらく遷移前と遷移後のシーン両方にLevelLoaderプレハブを配置する想定の作りになっているようです。 遷移後のシーンにもLevelLoaderを配置してみてもらえますか?
Ace230

2024/01/18 02:37

>遷移後のシーンにもLevelLoaderを配置してみてもらえますか? 遷移後のシーンに同じくプレハブを配置したのですが変わりませんでした。。。 ギガファイル便にてパッケージフォルダをアップロードしたので実際の挙動などがわかるかもしれません。 リンク:https://xgf.nu/7sAAH
Ratnaraj

2024/01/18 04:33

プロジェクトを確認しました。 回答の方に追記したのでそちらをご確認ください。
Ace230

2024/01/18 04:54

トランジションがうまく実行できるようになりました! 長い間付き合っていただきありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問