ゲーム開発していて、
そんなに重いゲームを作ってるわけではのに、
時に、シーンの遷移を少し待つようなパートがあったりします。
そういうところには、
「Loading...」といったテキストで示すようにしますが、
あまりに長いと、
バグった?と思われてしまいかねません。
なので、シーン移動の実装とともにセットで、
知っておきたいテクニックが、ローディングゲージの作り方です!
それに関して、とても有益なノウハウを掲載されている記事がこちら↓
簡単なローディング画面(読み込み中)の作成【Unityゲーム制作】
本記事では、
開発でよく使うテクニックの備忘録なので、
ローディングゲージの実装に加え、
現在のシーンから、次のシーンに移っても、
流れているBGMが途切れず再生されるように設計するというところを記しておきます。
まぁDontDestroyOnLoad()を使うだけですが・・・
ローディングゲージの作成
まず、Panel(LoadingPanelと命名)を作成します。
その配下にSlider、Textを作成します。
いい感じの大きさと高さに設定します。
Sliderは、参考記事から、0〜0.9に設定し、 Valueは0にしておきます。
Handleは、使わないので非表示にして問題ないでしょう。
また、Textの文字列は、「Loading ...」にします。
今回、UIのボタンおよびキーボードの入力で
ロードを発火したいので、Buttonも作成しておきます。
そのTextは「Start」にします。
次に、遷移先のシーンを作成(GameSceneと命名)、
BuildSettingに2シーンを追加しておきます。
それでは、以下のようにスクリプトを作成します(GameManager.csと命名)。
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using TMPro; using UnityEngine.SceneManagement; using UnityEngine.InputSystem; public class GameManager : MonoBehaviour { [SerializeField] GameObject _loadingUI; [SerializeField] Slider _slider; [SerializeField] Button startBtn; [SerializeField] TextMeshProUGUI _text; bool _loading = false; void Start() { startBtn.onClick.AddListener(LoadNextScene); } //ローディング中ならtrueを返す関数 bool CheckLoading() { return _loading; } //UIのボタンまたはEnterキーから処理される public void LoadNextScene() { if(CheckLoading()) { return; } _loading = true; _loadingUI.SetActive(true); StartCoroutine(LoadScene()); } void Update() { //Loading中はUpdate()処理を受け付けない if(CheckLoading()) { return; } // if (Input.GetKeyDown(KeyCode.Enter)) if(Keyboard.current.enterKey.isPressed) { LoadNextScene(); } } IEnumerator LoadScene() { AsyncOperation async = SceneManager.LoadSceneAsync("GameScene"); async.allowSceneActivation = false; while (!async.isDone) { _slider.value = async.progress; if (async.progress >= 0.9f) { _text.text = "Complete!"; // if (Input.GetKeyDown(KeyCode.Space)) if(Keyboard.current.spaceKey.isPressed) { async.allowSceneActivation = true; } } yield return null; } } }
空のゲームオブジェクト(GameManagerと命名)を作って、アタッチします。
インスペクターで各項目を漏れなく、紐付けます。
Startボタンをクリック(またはEnterキーを入力)すると、
LoadingPanelが表示されるはずです。
ロードに全く時間を要さないので、即ゲージがフルになっています。
このスクリプトでは、
ゲージがフルになってから(シーンに移る準備ができてから)
Spaceキーを入力しないと、次のシーンに切り替わらない設計なので、
まだ、ゲージがフルになっている状態を確認できますが、
そのような設計でなかった場合、
即次のシーンが表示され、
頑張って?作ったLoadingPanelを見ることもないでしょう^^;
なお、スクリプトではbool型関数を使って、
Loading中に、他の処理を受け付けないようにしています。
このようなバリア的な対策は、ゲーム開発には必須ですが、
UniTaskを使った最適な方法があるみたいなので、気になる方は調べてみてください。
(簡単に示せそうであれば、追記します)
また、キーボードの入力検出は、
Input Systemの方式を書いてます。
(旧のInputManagerを使う方はコメント部分を使用してください)
途切れないBGMの実装
冒頭にも触れましたが、
シーンが変わっても、途切れず再生され続けるBGMは
DontDestroyOnLoad()を使います。
その壊さないオブジェクトを
空のゲームオブジェクトで用意します(SoundManagerと命名)。
さらにその配下にBGMオブジェクトを作成します(BGMと命名)。
お好みの音楽ファイルをSoundManagerオブジェクトにドラッグ&ドロップすると、
AudioSourceコンポーネントがアタッチされます。
PlayOnAwake、Loopにチェックを入れて、
Volumeも0.1程度にします。
準備は、これでOK。
以下のようなスクリプトを作成し()、SoundManagerオブジェクトにアタッチします。
using System.Collections; using System.Collections.Generic; using UnityEngine; public class SoundManager : MonoBehaviour { public static SoundManagerL Instance = null; private void Awake() { if (Instance != null) { Destroy(this.gameObject); //重複しないように破壊 return; } DontDestroyOnLoad(this.gameObject); Instance = this; } }
ちなみに参考にさせていただい記事はこちら↓
【Unity】シーンをまたいでBGMを鳴らし続ける
SoundManagerのようなゲームのサウンドを司るようなオブジェクトなら、
DontDestroyOnLoad()で、ずっとインスタンスでもたせるが適しているかもしれませんね。
ゲーム開発でサウンドを実装するなら、
こちらでオススメのテクニックをまとめているのでをご参考ください↓
以上、
ローディングゲージとなり続けるBGMの実装したシーン遷移テクニックでした。
その他、シーン遷移で必要な機能があれば、また追記していきますので、
よければ、ブックマークください^^