📚

【Unity】SceneSystemを試してみた【AnnulusGames】

2024/01/05に公開

概要

当記事は、ゲームエンジンUnityにてAnnulusGamesさんの提供しているSceneSystemと呼ばれるライブラリを試した体験を整理した記事です。

元々自身のProjectでは自作のScene管理システムを使っていたのですが、ふとSNSで見かけ、ドキュメントへ飛んだところ、Scene管理の仕組みや指針、考え方に共感する部分があり、より洗練されていたこちらを勉強を兼ねて触ってみることにしました。

使用環境

  • Unity 2022.3.16f1
  • Windows11 home
  • JetBrains Rider 2023.3.2

導入

公式のドキュメントにも記載がありますが、Package ManagerからAdd package from git URLで以下のURLを入力します。

https://github.com/AnnulusGames/SceneSystem.git?path=/Assets/SceneSystem

実際に触ってみた

使い方はとても簡単でした。インポート後、任意の2シーンを用意し、プログラムなどからScenes.LoadSceneAsync(0)などと記載するだけです。引数の整数(int)はBuildSettingsのScenes In Buildに登録したSceneの索引です。

ここからは、実際に0から新規プロジェクトで動作させてみたところのサンプルです。この後紹介する2つの実装サンプルは、SceneSystemのプロジェクトに元から入ってるサンプルをより簡略化したものです。手っ取り早く動作確認をしてみたい方は、SceneSystem > Samples > LoadingScreenSampleフォルダ下の内容をUnityに取り込んでみてください。

簡単なScene切り替えの実装サンプル

新規のUnityProjectを立ち上げ、Sceneを二つ作ります。今回は見た目がそっくりなシーンをひとつ作ってから複製し、パラメーターを若干変える形でサクッと進めてみます。

using AnnulusGames.SceneSystem;
using UnityEngine;
using UnityEngine.UI;

public class SceneSystemScriptTest : MonoBehaviour
{
    [SerializeField] Button button;
    [SerializeField] int sceneIndex;
    
    void Start()
    {
        button.onClick.AddListener(() =>
        {
           Scenes.LoadScene(sceneIndex);
        });   
    }
}


SceneIndexの数値はBuildSettingsの内容ときちんと合わせましょう

SceneSystemではプログラムからSceneを呼び出すこともできますが、SceneをInspectorから参照できる様にするSceneReferenceクラスも存在し、そちらを使ってSceneへの参照を用意し、Sceneを切り替えることも可能です。

sing AnnulusGames.SceneSystem;
using UnityEngine;
using UnityEngine.UI;

public class SceneSystemReferenceTest : MonoBehaviour
{
    [SerializeField] Button button;
    [SerializeField] SceneReference sceneReference;
    
    void Start()
    {
        button.onClick.AddListener(() =>
        {
           Scenes.LoadScene(sceneReference);
        });   
    }
}


SceneReferenceには遷移先のSceneをセットしています

どちらスクリプトをアタッチした場合であっても問題なくScene切り替えが動作します。

Roading画面を交えたScene切り替えの実装サンプル

SceneSystemには、Now Roading ... などでお馴染みのローディング画面をお手軽に作れるクラスLoadingScreenがあるとのことなので使ってみましょう。

仕組みとしては、遷移先のSceneが表示される前(正確には、現在のSceneが閉じる前)にローディング画面を表示し、遷移先のSceneの準備(GameObjectなどのHierarchy上のデータローディング他)が終わったらこのローディング画面を消す -> Scene遷移という流れです。

まずは、ローディング画面用にCanvasコンポーネントを根元に置いたPrefabを作成します。このPrefabの根元に、LoadingScreenコンポーネントもアタッチしましょう。

先ほどの、SceneSystemReferenceTest.csにさらに手を加えてみます。

sing AnnulusGames.SceneSystem;
using UnityEngine;
using UnityEngine.UI;

public class SceneSystemReferenceTestAdvance : MonoBehaviour
{
    [SerializeField] Button button;
    [SerializeField] SceneReference sceneReference;
    [SerializeField] LoadingScreen loadingScreenPrefab;
    
    void Start()
    {
        button.onClick.AddListener(() =>
        { 
            LoadingScreen loadingScreen = Instantiate(loadingScreenPrefab);
            Scenes.LoadSceneAsync(sceneReference).WithLoadingScreen(loadingScreen);
        });   
    }
}

追加した部分は、以下の2点です

  • ボタン押下後にPrefabをInstantiateすること
  • Scene遷移方式をLoadSceneAsyncメソッドに変更し、その処理の後ろに.WithLoadingScreenメソッドの記載を加える

これでローディング画面の完成です。

ローディングの進捗を示すバーとかがない?
ご安心ください、そういったニーズに対応するためにLoadingScreenコンポーネントには様々なプロパティが用意されています。詳しくは公式ドキュメントに譲りますが、例えばOn Loading(Single)はローディングの進捗状況(0~1.0、つまり0%~100%)が進む都度イベントを発生させ値を出力する構造になっています。そこでここにSliderコンポーネントのValueプロパティなどを紐づけてあげれば、それっぽいものが簡単に実現します。

ところで、私のPC性能良すぎてローディングが一瞬すぎて確認しようがないんだけど!と嘆くそこのあなた! LoadingScreenコンポーネントにはなんと「最低ローディング時間」の設定することも可能です。(上記のサンプルも全てその設定が入っています)


Minimum Loading Timeの2が、最低でもロードに2秒かける意味に

終わりに

使ってみたところ簡潔にSceneの生成と破棄のプログラムが記載でき、とても便利だった。また、当記事では紹介していなかった複数シーンを管理するためのContainerクラス、関数型プログラミングと相性の良いLoadSceneOperationHandle構造体なども便利だったので、次の機会に取り上げてみたい。

余談

自身の環境のせいなのかgitのURLからのインポートができなかったので、ProjectのZipデータを入手->解凍->直接放り込み動かしました。そしてまたまた自前環境が変なのか、UniRxインポートしていたのにかかわらず、構文解析で条件コンパイルが作動しておらず、container系のExtentionsが参照できない問題が起きたりしました。なんでジャ・・・。なお、当記事では入門者向けにUniRxなどの高度なライブラリは使わない方向で書いています。

関連リンク

Discussion