Unity フレームワークの学習 - シーン切り替えマネージャー

活動風景

スクリプトを使用してインスタンス化されたゲーム オブジェクトは、アクティブ シーンに生成されます。

どのシーンがアクティブなシーンであるか、現在のスカイボックスはそのシーンのスカイボックスを使用します。

アクティブなシーンになれるのは 1 つのシーンだけです。

階層内のシーンを右クリックし、[アクティブ シーンの設定] をクリックして、このシーンをアクティブ シーンとして手動で設定します。SceneManager.SetActiveScene メソッドを使用して、ロードされたシーンをアクティブ シーンとして設定することもできます。

非同期ロード

AsyncOperation 関連のコードはコルーチンで記述する必要があります。

AsyncOperation オブジェクト名 = SceneManager.LoadSceneAsync (文字列シーン名) は、
シーンの非同期読み込みをオンにし、非同期読み込み情報を AsyncOperation オブジェクトに保存します。

AsyncOperation 型 object.allowSceneActivation は
bool 型を返し、シーンがロードされた直後にシーンをアクティブ化できるかどうかを示します。
値 true は、シーンが非同期でロードされると、シーンがすぐにアクティブ化されることを意味します。
false の値は、シーンがロードされてもシーンがアクティブ化されないことを意味します。コードを使用してこの変数の値を再度 true に変更するまで、シーンはアクティブ化されません。

AsyncOperation 型の object.progress は
、0 ~ 1 の範囲の float 型を返します。0 で開始し、1 で完了する非同期読み込みの進行状況を示します。
注: AsyncOperation 変数 .allowSceneActivation の値が false の場合、このパラメーターの値は、AsyncOperation 変数 .allowSceneActivation の値が達するまで最大 0.9 で固定されます。 trueになるとパラメータの値が1になります

AsyncOperation 型 object.isDone は
bool 型を返します。非同期ロードが完了したかどうかを示します。値は完了した場合は true、完了していない場合は false です。
AsyncOperation 型 object.progress の値が 1 の場合、この時点でこの変数の値は true ですが、これにより新しい新しいシーンがアクティブになります。AsyncOperation 型 object.isDone が true であることを観察することは一般に困難です。

AsyncOperation 型 object.priority は
int 型を返し、非同期操作の優先順位を設定するために使用されます。
複数の非同期操作がキューに登録されている場合、優先度の高い非同期操作が最初に実行されます。ただし、非同期操作がバックグラウンド スレッドで開始された場合、優先度を変更しても効果はありません。

AsyncOperation.completed は
、AsyncOperation パラメータを持つ Action イベントです。AsyncOperation パラメータには、この非同期読み込みの情報が格納されます。
非同期ロードが完了したとき、つまり、AsyncOperation 型 object.isDone の値が true になったとき、このイベントは 1 回実行されます。
 

LoadSceneManager コード

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.Events;

/// <summary>
/// 切换场景的管理器
/// </summary>
public class LoadSceneManager : SingletonPatternBase<LoadSceneManager>
{
    /// <summary>
    /// 重新切换当前场景
    /// </summary>
    public void LoadActiveScene()
    {
        SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
    }

    /// <summary>
    /// 切换到下一个场景,是否场景循环,最后一个场景切换是切换为第一个场景
    /// </summary>
    public void LoadNextScene(bool isCyclical=false)
    {
        int buildIndex = SceneManager.GetActiveScene().buildIndex + 1;

        //检测要切换的新场景的下标是否越界     这个参数的意思是BuildSettings中的场景总数
        if (buildIndex > SceneManager.sceneCountInBuildSettings-1)
        {
            if (isCyclical)
                buildIndex = 0;
            else
            {
                Debug.LogWarning($"加载场景失败!要加载的场景的索引是{buildIndex},越界了");
                return;
            }
        }

        SceneManager.LoadScene(buildIndex);
    }

    /// <summary>
    /// 加载上一个场景,包括可选择的场景循环功能
    /// </summary>
    public void LoadPreviousScene(bool isCyslical=false)
    {
        int buildIndex = SceneManager.GetActiveScene().buildIndex - 1;

        if (buildIndex < 0)
        {
            if (isCyslical)
            {
                buildIndex = SceneManager.sceneCountInBuildSettings - 1;
            }
            else
            {
                Debug.LogWarning($"加载场景失败!要加载的场景索引是{buildIndex},越界了!");
                return;
            }
        }

        SceneManager.LoadScene(buildIndex);
    }

    /// <summary>
    /// 异步加载场景  根据名字来切换场景
    /// </summary>
    public void LoadSceneAsync(string sceneName, UnityAction<float> loading = null,
        UnityAction<AsyncOperation> completed = null, bool setActiveAfterCompleted = true, LoadSceneMode mode = LoadSceneMode.Single)
    {
        MonoManager.Instance.StartCoroutine(LoadSceneCoroutine(sceneName, loading, completed, setActiveAfterCompleted, mode));
    }

    IEnumerator LoadSceneCoroutine(string sceneName, UnityAction<float> loading = null,
        UnityAction<AsyncOperation> completed = null, bool setActiveAfterCompleted = true, LoadSceneMode mode = LoadSceneMode.Single)
    {
        //开始加载资源
        AsyncOperation asyncOperation = SceneManager.LoadSceneAsync(sceneName, mode);

        asyncOperation.allowSceneActivation = false;  //资源加载最多到0.9

        //等待资源加载完毕
        while (asyncOperation.progress < 0.9f)
        {
            loading?.Invoke(asyncOperation.progress);
            yield return null;
        }

        //当asyncOperation.allowSceneActivation 为false,则asyncOperation.Progress最多只能到达0.9
        //我们人为把它们凑成1,可以方便外部进度条的显示
        loading?.Invoke(1);

        asyncOperation.allowSceneActivation = setActiveAfterCompleted;

        //加载资源完毕后执行的逻辑
        completed?.Invoke(asyncOperation);
    }

    /// <summary>
    /// 异步加载场景 根据索引来切换场景
    /// </summary>
    public void LoadSceneAsync(int sceneIndex,UnityAction<float>loading=null, 
        UnityAction completed = null,bool setActiveAfterCompleted=true, LoadSceneMode mode = LoadSceneMode.Single)
    {
        MonoManager.Instance.StartCoroutine(LoadSceneCoroutine(sceneIndex,loading, completed,setActiveAfterCompleted, mode));
    }

    IEnumerator LoadSceneCoroutine(int sceneIndex, UnityAction<float> loading = null,
        UnityAction completed = null, bool setActiveAfterCompleted = true, LoadSceneMode mode = LoadSceneMode.Single)
    {
        //开始加载资源
        AsyncOperation asyncOperation = SceneManager.LoadSceneAsync(sceneIndex, mode);

        asyncOperation.allowSceneActivation = false;  //资源加载最多到0.9

        //等待资源加载完毕
        while (asyncOperation.progress < 0.9f)
        {
            loading?.Invoke(asyncOperation.progress);
            yield return null;
        }

        //当asyncOperation.allowSceneActivation 为false,则asyncOperation.Progress最多只能到达0.9
        //我们人为把它们凑成1,可以方便外部进度条的显示
        loading?.Invoke(1);

        asyncOperation.allowSceneActivation = setActiveAfterCompleted;

        //加载资源完毕后执行的逻辑
        completed?.Invoke();
    }


}

テストスクリプト

[MenuItem("我的菜单/同步切换场景/重新切换到上一个场景")]
    static void Method3()
    {
        LoadSceneManager.Instance.LoadPreviousScene();
    }

    [MenuItem("我的菜单/异步切换场景/重新切换到场景1")]
    static void Method4()
    {
        LoadSceneManager.Instance.LoadSceneAsync("New Scene 1", (obj) =>
         {
             Debug.Log("加载进度是:" + obj * 100 + "%");
         }, (obj) =>
         {
             Debug.Log("加载完成了!");
         });
    }

Unity シーンクラス (シーンクラス)

Scene クラスのオブジェクトは、シーン情報を格納するために使用されます。

シーン タイプ object.buildIndex は
、ビルド設定ウィンドウ内のシーンのインデックスを示す int タイプを返します。
シーンが無効なシーンの場合、この変数の値は -1 になります。
シーンが AssetBundle を通じてロードされたシーンの場合、この変数の値も -1 になります。

シーン タイプ object.isDirty は
、シーンが変更されているかどうかを示す bool タイプを返します。
エディター モードでシーンを変更しても保存しない場合、この変数の値は true になります。シーンが保存されると、この変数の値は false になります。

シーン タイプ object.isLoaded は、
シーンがロードされている場合に true を返します。シーンがロードされていない場合、またはロードされていない場合は false を返します。

シーン タイプ object.name は
、シーンの名前を示す文字列タイプを返します。末尾には、
プロジェクト ウィンドウでの名前である接尾辞 .unity は含まれません。
注: この変数がシーン名を正しく返すには、シーンがロードされている必要があります。シーンがロードされていない、またはロードされていない場合、戻り値は「Null」になります。

Scene object.path は
、シーンのパスを示す文字列タイプを返し、最後にサフィックス .unity が付きます。
例:
Assets/AssetBundleAssets/Scenes/TestScenes/Test.unity

シーン タイプ object.rootCount は
、シーン内のすべてのルート ゲーム オブジェクトの Transform コンポーネントの合計数を示す int タイプを返します。

シーン タイプ object.GetRootGameObjects は
、シーン内のすべてのルート ゲーム オブジェクトを表す GameObject[] タイプを返します。
非表示のルート ゲーム オブジェクトも含まれますが、DontDestoryOnLoad のルート ゲーム オブジェクトは含まれません。

シーンタイプ object.IsValid
シーンが存在する場合、それは有効なシーンであり、この変数の値は true です。
シーンが存在しない場合、それは無効なシーンであり、この変数の値は false です
。 EditorSceneManager.OpenScene 返されたシーンの IsValid の値が false です

演算子 != は 2 つのシーン オブジェクト間で使用でき、
2 つのシーンが異なる場合は true を返し、異なる場合は false を返します。

演算子 == は 2 つのシーン オブジェクト間で使用でき、
2 つのシーンが同じ場合は true を返し、そうでない場合は false を返します。

Unity SceneManager クラス (シーン マネージャー、シーンのロードとシーンの切り替えに使用)

まず、ジャンプしたいシーンをファイル - ビルド設定にドラッグします。

UnityEngine.SceneManagement を使用して、最初に名前空間を導入する必要があります。

SceneManager.sceneCount
現在ロードされているシーンの数。

SceneManager.sceneCountInBuildSettings [
ビルド設定] ウィンドウに追加されたシーンの数。
エディター モードの場合、再生モードに入る前に開いていたシーンも含まれます。手動で [ビルド設定] ウィンドウにドラッグしていない場合は、[ビルド設定] ウィンドウにもインデックスが付けられますが、それを見ることはできません。このインデックスは、表示される最大値の 1 より大きくなります。

SceneManager.CreateScene(int scene name) は
、現在のシーンに重ねられる空のシーンを作成します。
作成されたシーンに重複した名前が付いている場合、エラーが報告されます。
シーン名は Hierarchy ウィンドウに表示されます。
エディタ スクリプトやツールを作成する場合など、編集中にシーンを作成する場合は、EditorSceneManager.NewScene を使用する必要があります。

SceneManager.CreateScene(string シーン名, CreateSceneParameters シーンを作成するためのさまざまなパラメーター) は
、現在のシーンに重ねられる空のシーンを作成します。
作成されたシーンに重複した名前が付いている場合、エラーが報告されます。
シーン名は Hierarchy ウィンドウに表示されます。
エディタ スクリプトやツールを作成する場合など、編集中にシーンを作成する場合は、EditorSceneManager.NewScene を使用する必要があります。

SceneManager.GetActiveScene() は
、現在のシーンに関する情報を表す Scene オブジェクトを返します。

SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
同期を使用して、現在のシーンに再度切り替えます。

SceneManager.GetActiveScene().buildIndex+1 は、[ビルド設定] ウィンドウ内の次のシーンのインデックスを表します。

SceneManager.GetActiveScene().name
文字列タイプ。現在のシーンの名前を示します。SceneManager.LoadScene とともに使用して、現在のシーンを再ロードできます

SceneManager.GetSceneAt(int index) は、
現在ロードされているシーンのリスト内の指定されたインデックスにあるシーンに関する情報を返します。
インデックスは 0 以上である必要があり、最小値は 0 です。負の数である場合、またはインデックスが範囲外の場合、エラーが報告されます。

SceneManager.GetSceneByBuildIndex (ビルド設定ウィンドウのシーンの int インデックス) は、
渡されたインデックスに基づいてビルド設定のシーン情報を返します。
情報を返すには、シーンが [ビルド設定] ウィンドウ内にあり、現在ロードされている必要があります。それ以外の場合は、無効な Scene オブジェクトが返されます。
インデックスは 0 以上である必要があり、最小値は 0 です。負の数である場合、またはインデックスが範囲外の場合、エラーが報告されます。

SceneManager.GetSceneByName(string シーン名) は、
現在ロードされているシーン内で、指定されたシーン名のシーンを検索します。
見つかった場合は、このシーンの情報を表す Scene オブジェクトが返されます。見つからない場合は、無効な Scene オブジェクトが返されます。
シーン名は、[ビルド設定] ウィンドウに表示される名前の最後の部分にすることができます。その場合、最初に一致したシーン情報が返されます。
シーン名は、[ビルド設定] ウィンドウに表示されるパスにすることもできます。その場合、正確に一致するシーン情報が返されます。
シーン名は大文字と小文字が区別されません。
シーン名には .unity 拡張子を含めることはできません。

SceneManager.GetSceneByPath(string scene path) は、
現在ロードされているシーン内で、指定されたリソース パスを持つシーンを検索します。
見つかった場合は、このシーンの情報を表す Scene オブジェクトが返されます。見つからない場合は、無効な Scene オブジェクトが返されます。
シーンへのパスは、プロジェクト フォルダーからの相対パスである必要があります (例: "Assets/MyScenes/MyScene.unity")。

SceneManager.LoadScene(ビルド設定ウィンドウのシーンの int インデックス、シーンをロードする LoadSceneMode モード);
        指定されたインデックスでシーンを同期的にロードします。
        最初のパラメータは文字列タイプにすることができるため、指定されたシーンはシーン名またはシーン パスに基づいてロードされます。このとき、この名前のシーンは事前にBuild Settingsウィンドウに配置されているか、事前にAssetBundleを使用してロードされているため、この方法が有効になります。何もない場合は、エラーが報告されます。注: シーン名には .unity 接尾辞は含まれません。また、シーン名が同じであることはできません。シーン名が同じ場合、最初に一致したシーンがロードされます。シーン パスを使用できます (例: Assets/AssetBundleAssets/Scenes/TestScenes/Scene1.unity)。2
        番目のパラメーターとして LoadSceneMode.Single を使用すると、ロード後に自動的にシーンに切り替わります。元のシーンはアンインストールされます。これはデフォルトで使用されます。
        LoadSceneMode.Additive が 2 番目のパラメーターとして使用される場合、シーンはロード後に元のシーンに重ねられます。元のシーンはアンインストールされず、アクティブなシーンは元のシーンのままになります。
        このメソッドを使用してシーンをロードしても、すぐにはロードされませんが、次のフレームでロードが開始されます。また、このメソッドは同期メソッドであるため、遅延が発生する可能性があるため、非同期読み込みの LoadSceneAsync メソッドを使用することをお勧めします。

SceneManager.LoadSceneAsync (int は [ビルド設定] ウィンドウのシーンのインデックス、LoadSceneMode はシーンのロード モード);
        指定されたインデックスでシーンを非同期的にロードします。
        最初のパラメータは文字列タイプにすることができるため、指定されたシーンはシーン名またはシーン パスに基づいてロードされます。このとき、この名前のシーンは事前にBuild Settingsウィンドウに配置されているか、事前にAssetBundleを使用してロードされているため、この方法が有効になります。何もない場合は、エラーが報告されます。注: シーン名には .unity 接尾辞は含まれません。また、シーン名が同じであることはできません。シーン名が同じ場合、最初に一致したシーンがロードされます。シーン パスを使用できます (例: Assets/AssetBundleAssets/Scenes/TestScenes/Scene1.unity)。2
        番目のパラメーターとして LoadSceneMode.Single を使用すると、ロード後にシーンに切り替えることができ、元のシーンはアンロードされます。これはデフォルトで使用されます。
        2 番目のパラメータとして LoadSceneMode.Additive を使用すると、ロード後にシーンを元のシーンに重ね合わせることができます。元のシーンはアンインストールされず、アクティブなシーンは元のシーンのままになります。
        このメソッドを使用してシーンをロードしても、ゲームはフリーズしません。これは、シーンの進行状況バーと組み合わせてよく使用されます。シーンのロード中に進行状況バーの進行を制御できます。
        このメソッドの戻り値の型はAsyncOperation型であり、この型のオブジェクトによって非同期ロードが完了したかどうかを判断できます。詳細については、AsyncOperation クラスを参照してください。

SceneManager.MergeScenes(Scene scene 1, Scene scene 2) は、
シーン 1 のすべてのゲーム オブジェクトをシーン 2 に転送し、シーン 1 がアンロードされます。
一般に、このメソッドは、シーンをロードするために LoadSceneMode.Additive が使用される場合にのみ使用できます。
シーン 1 とシーン 2 は両方ともシーンをロードする必要があります。
元のシーン 1 がアクティブなシーンの場合、それがアンインストールされると、Hierarchy ウィンドウの上部にある最初のシーンがアクティブなシーンになります。
元のシーン 1 がアクティブ シーンではない場合、アンインストールしてもアクティブ シーンは変わりません。

SceneManager.MoveGameObjectToScene(GameObject は移動されるゲーム オブジェクト、Scene はシーンに移動します) は、
ゲーム オブジェクトを、それが配置されているシーンからターゲット シーンに移動します。
一般に、このメソッドは、シーンをロードするために LoadSceneMode.Additive が使用される場合にのみ使用できます。
移動先のシーンはロードされたシーンである必要があります。
移動するゲーム オブジェクトが null の場合、このメソッドは効果がありません。
移動先のシーンがロードされていない場合、または無効なシーンの場合は、エラーが報告されます。

SceneManager.SetActiveScene(Scene シーン名) は、
指定されたシーンをアクティブ シーンとして設定します。

SceneManager.UnloadSceneAsync(ビルド設定ウィンドウの int シーン インデックス)
SceneManager.UnloadSceneAsync(文字列シーン名またはシーン パス)
SceneManager.UnloadSceneAsync(シーン シーン オブジェクト)
SceneManager.UnloadSceneAsync(ビルド設定ウィンドウの int シーン インデックス、UnloadSceneOptions はシーン オプションをアンロードします)
SceneManager.UnloadSceneAsync (文字列シーン名またはシーン パス、シーンをアンロードするための UnloadSceneOptions オプション)
SceneManager.UnloadSceneAsync (シーン シーン オブジェクト、シーンをアンロードするための UnloadSceneOptions オプション)
指定されたシーンとこのシーン内のすべてのゲーム オブジェクトを破棄します。
このメソッドは、LoadSceneMode.Additive を使用してロードされたシーンに対してのみ有効です。現在のゲームにシーンが 1 つしかない場合、このメソッドは無効であり、コンソールは黄色の警告を報告します。
このメソッドは、シーン リソースをメモリからアンロードしません。リソースを解放したい場合は、このメソッドを呼び出した後、Resources.UnloadUnusedAssets メソッドを呼び出す必要があります。戻り値の型は AsyncOperation 型です。このオブジェクトを使用して
、非同期操作が完了したかどうかを判断します。

SceneManager.activeSceneChanged
UnityAction<Scene,Scene> タイプのイベント。
このイベントは、アクティブなシーンが変更されるときに 1 回実行されます。
最初のパラメータは元のアクティビティ シーンを表し、2 番目のパラメータは後続のアクティビティ シーンを表します。

SceneManager.sceneLoaded
UnityAction<Scene,LoadSceneMode> タイプのイベント。
このイベントは、新しいシーンがロードされるたびに実行されます。
最初のパラメータはロードされる新しいシーンを示し、2 番目のパラメータはこのシーンのロード モードを示します。

SceneManager.sceneUnloaded
UnityAction<Scene> タイプのイベント。
このイベントは、シーンがアンロードされるたびに実行されます。
パラメータは、アンロードされたシーン オブジェクトを表します。

おすすめ

転載: blog.csdn.net/zaizai1007/article/details/132377762
おすすめ