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

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

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

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

Unity

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

Q&A

解決済

3回答

1747閲覧

【Unity】シーンの非同期処理について(Now Loadingの機能を実装したい)

reishisu

総合スコア39

C#

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

Unity

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

0グッド

0クリップ

投稿2018/08/14 15:30

編集2018/08/14 23:20

前提・実現したいこと

現在Unityでシーンを非同期でロードして遷移する処理を作成しています。

ですが、ロード中に画面にロード中と書かれた画像を表示するように作成しているのですが全く表示されておらず勝手に遷移されてしまい困っております。

Debug.LogでLoadingSceneクラスの色々な部分を表示させてみましたが思うように動作していなくて個人的に原因は、3つのゲームオブジェクト(シーン遷移に関するゲームオブジェクト、動画関連のゲームオブジェクトと音楽関連のゲームオブジェクト)に対してDontDestroyOnLoadを行なって残るようにした為と考えたのですがその部分をコメントアウトして実行しても変わりませんでした。

ですので申し訳ないですが、どなたか原因が分かる方がいらっしゃいましたら教えて頂きたいです...

また、周りに聞ける方もいなく独学で色々なサイトを見ながらやっているのでコルーチンやシーン遷移に関する認識がずれていたら指摘していただきたいです。

【追記】
OpeningManagerクラスとSceneControllerクラスのコードを追加しました。

問題

  1. async.allowSceneActivation = false;

LoadingSceneクラスの行で勝手に遷移されないようにしているのに勝手にTitleSceneに遷移される。

  1. 遷移する際にロード画面が出てくるはずなのに一瞬フリーズして遷移されてしまう。
  2. LoadingSceneクラスのwhileを抜けた後の行が実行されていない。

該当のソースコード

最初に読み込まれるOpeningSceneでTitleSceneへ遷移させるように命令をだすクラス(実際には【SceneController】クラスのメソッドを実行している)

C#

1using UnityEngine; 2 3/// <summary> 4/// オープニングシーンを管理するクラス 5/// </summary> 6public class OpeningManager : MonoBehaviour { 7 8 public static bool loadTwice; // 読み込みが2回目以降か判定する 9 10 /// <summary> 11 /// シーンが呼ばれた際に最初に読み込まれる関数 12 /// </summary> 13 private void Awake() { 14 // 読み込みが2回目以降か? 15 if (loadTwice) MovieManager.instance.SetTargetCamera( Camera.main ); 16 else loadTwice = true; 17 // すぐ再生させたいので再生スイッチをオンにする 18 MovieManager.PlaySwitchFlg = true; 19 } 20 21 /// <summary> 22 /// 毎フレーム呼び出されるメソッド 23 /// </summary> 24 private void Update() { 25 26 // 再生スイッチがON && 再生中 27 if ( MovieManager.PlaySwitchFlg && MovieManager.instance.MovieIsPlaying() ) { 28 // クリックする 29 if ( Input.GetMouseButtonDown(0) ) { 30 SoundManager.instance.PlayClickSE(0); 31 MovieManager.instance.StopMovie(); 32 SceneController.instance.LoadTitle(); 33 } 34 double remainingTime = MovieManager.instance.GetMovieClipLength() - MovieManager.instance.GetPlayingPoint(); 35 // 再生時間が0.05秒を切ったら終了して次のシーンへ 36 if ( remainingTime < 0.05 ) { 37 MovieManager.instance.StopMovie(); 38 SceneController.instance.LoadTitle(); 39 } 40 } 41 } 42} 43

OpeningSceneで呼び出されるクラス(実際にシーンの遷移処理は【LoadingScene】クラスが行なっている)

C#

1using UnityEngine; 2using UnityEngine.SceneManagement; 3 4/// <summary> 5/// シーンの遷移をコントロールするクラス 6/// </summary> 7public class SceneController : MonoBehaviour { 8 9 public static SceneController instance; // シングルトンインスタンス 10 11 /// <summary> 12 /// シーンが呼ばれた際に最初に読み込まれる関数 13 /// </summary> 14 private void Awake() { 15 if (instance == null) { 16 instance = this; 17 DontDestroyOnLoad(gameObject); 18 } else Destroy(gameObject); 19 } 20 21 /// <summary> 22 /// タイトルのシーンをロードする 23 /// </summary> 24 public void LoadTitle() { 25 SoundManager.instance.PlayBGM(0); 26 LoadingScene.next = "TitleScene"; 27 SceneManager.LoadScene("LoadingScene"); 28 } 29}

実際にLoadingSceneからTitleSceneへ遷移させるクラス

C#

1using System.Collections; 2using UnityEngine; 3using UnityEngine.SceneManagement; 4 5/// <summary> 6/// 遷移したいシーンをロードして遷移するクラス 7/// </summary> 8public class LoadingScene : MonoBehaviour { 9 10 private AsyncOperation async; // 非同期動作で使用するAsyncOperation 11 public static string next = "TitleScene"; // 次のシーンの名前を入れる 12 13 14 /// <summary> 15 /// シーンが呼ばれた際に最初に読み込まれる関数 16 /// </summary> 17 private void Awake() { 18 StartCoroutine(LoadNextScene()); 19 } 20 21 public IEnumerator LoadNextScene() { 22 Debug.Log("ロード画面 : " + next); 23 Debug.Log("現在読み込まれてるシーンの数 : " + SceneManager.sceneCount + " 個"); 24 25 foreach (Scene s in SceneManager.GetAllScenes()) { Debug.Log(s.name); } 26 27 // 非同期でロード開始させる 28 async = SceneManager.LoadSceneAsync(next); 29 30 // ロード完了時に自動的に遷移させないようにする 31 async.allowSceneActivation = false; 32 33 Debug.Log("allowSceneActivation : " + async.allowSceneActivation); 34 Debug.Log("start while : " + async.progress); 35 36 // ロードが完了していない間ループする 37 while ( !async.isDone ) { 38 Debug.Log("while : " + async.progress); 39 Debug.Log("isDone : " + async.isDone); 40 yield return null; 41 } 42 43 Debug.Log("end while : " + async.progress); 44 45 // ↓上の行でfalseにしてコメントアウトしているので勝手に遷移はされ無いはず? 46 // async.allowSceneActivation = true; 47 } 48}

実行結果

実行結果は
「OpeningScene(最初に読み込まれるシーン。OpeningSceneクラスとSceneControllerクラスのインスタンスを持っている)」

「LoadingScene(LoadingSceneクラスを実行しているシーン)」

「TitleScene(遷移先のシーン)」へ遷移しております。

イメージ説明

補足情報(FW/ツールのバージョンなど)

MacBook Pro (15-inch, 2016)
プロセッサ : 2.6 GHz Intel Core i7
メモリ : 16 GB 2133 MHz LPDDR3
OS : macOS High Sierra
バージョン : Unity 2018.2.2f1

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

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

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

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

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

guest

回答3

0

自己解決

結局自己解決してしまい、ご迷惑おかけしてすみませんでした。
同じ悩みで迷っている方がいらっしゃいましたら解決策と自分なりの原因考察致しましたので参考にしていただけると幸いです。
###解決策
LoadingScene.csのAwake関数をStart関数にしてあげることで上手く動作しました。

###原因考察
私の推測で申し訳ないのですが、シーン遷移の処理をAwake関数で呼び出していることでStart関数が実行される前に次のシーンへ行ってしまい1フレームも実行されなくて表示されなかったと考えました。

投稿2018/08/18 10:00

編集2018/08/18 10:19
reishisu

総合スコア39

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

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

0

AsyncOperation.allowSceneActivationのリファレンス

allowSceneActivation=falseにすると、isDoneがtrueにならなくなるので、そのコードでは一生画面遷移が発生しないかと思います。(報告されている実行結果と違っていることは謎ですが。)終了判定はリンクの先にあるようにasync.progress >= 0.9fで行いましょう。

実行結果通りなら、他にLoadSceneをしてしまっているところはありませんか?

投稿2018/08/15 09:36

編集2018/08/15 09:37
takezoux2

総合スコア3

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

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

reishisu

2018/08/15 10:29 編集

リンクありがとうございます! ちゃんと無限ループになった時に変更したいと思います٩(ˊωˋ*)و シーンの遷移はSceneControllerを経由してLoadingSceneで必ず実行するようにしているのでここにしか遷移する処理は書いておりません(><) 【追記】質問に対してちゃんとした回答なってなくてすみません、、、 もう一度全スクリプトに対してSceneManagerが呼ばれてないかチェックしましたがやはりSceneControllerとLoadingSceneでしか使用されておりませんでした…
reishisu

2018/08/15 10:12 編集

関係ないと思うで参考にならないかもしれないですが文にもありますように、最初のOpeningSceneというシーンで、SceneControllerをアタッチしたゲームオブジェクト(LoadingSceneに遷移させるゲームオブジェクト)とMovieManagerのスクリプトをアタッチしたゲームオブジェクト(動画の再生、停止、再生状況などを管理するゲームオブジェクト)とSoundManagerのスクリプトをアタッチしたゲームオブジェクト(BGM、SEの再生、停止、再生状況などを管理するゲームオブジェクト)はDontDestroyOnLoadに設定しているのでこの3つはシーンに残り続けております。
guest

0

LoadSceneAsync

使いましょう

投稿2018/08/15 08:34

takezoux2

総合スコア3

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

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

reishisu

2018/08/15 09:09

回答ありがとうございます! それは3つめのコードで利用しておりますので確認していただけるとありがたいです(><)
reishisu

2018/08/15 09:13

ちなみに使用しているクラス名はLoadingSceneです
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問