【Unity】シーンの雛形を作れるScene Template機能の使い方まとめ

Unityのシーンテンプレートの使い方をまとめました。

Unity2020.3.15f2

はじめに

Unity2020.2からシーンを作成する際に、シーンの初期状態を幾つかのテンプレートから選択できるウィンドウが表示されるようになりました。

New Sceneウィンドウ

これはシーンテンプレートとよばれる新機能で、そのプロジェクトに合わせたシーンテンプレートを作成して保存しておくこともできます。
本記事ではこの機能の使い方についてまとめます。

シーンテンプレートを作成する

それでは早速シーンテンプレートを作成します。
今回は以下のようなシーンをテンプレート化します。

元シーン

シーンテンプレートを作成するには、テンプレート化したいシーンを開いた状態でFile > Save As Scene Templateを選択します。

Save As Scene Template

またProjectビューで対象シーンを選択して右クリック > Create > Scene Template From Sceneでも作ることができます。

Projectビューで右クリック > Create > Scene Templateを選択すれば空のテンプレートも作れますが、これはあまり使わなそうです。

タイトルや説明などの情報を入力する

前節のようにして作成したテンプレートはアセットとして保存されます。
このアセットのInspectorではテンプレートのタイトルや説明文、サムネイルといった情報が設定できます。

Inspector

サムネイルは開いているシーンをキャプチャして作成することもできます(便利!)。
一通り設定するとシーン作成ページで以下のように表示されるようになります。

設定結果

シーンが参照するアセットをコピーするか設定する

さてシーンテンプレートのInspectorを見るとDependenciesという項目があることが確認できます。
ここにはそのシーンから参照されているアセットの一覧が表示されます。
そしてこのテンプレートから新しくシーンを作る際に、それらのアセットを直接参照するか、あるいは複製して参照するかを設定できます。

Dependencies

チェックをつけた状態だとそのアセットは複製され、シーンと同階層に作られるフォルダの中に格納されます。
チェックを外すと元のシーンと同じアセットが参照され、その変更はテンプレートから作成したシーンにも反映されます。

また、Project Settingsからは対象のアセットの型ごとに複製の設定が行えます。

Project Settings

上図の通り、それぞれの型について以下の設定ができます。

  • テンプレートを作成したときにその型のCloneチェックボックスがOFFになるかどうか
  • テンプレートを作成したときにDependenciesにその型が表示されるか

またここに表示されていない型を複製対象として登録することもできます。

テンプレートからシーンが作成される前や後の処理を書く

ISceneTemplatePipelineを使うと、テンプレートからシーンが作成される前後の処理を書くことができます。
これを行うにはまずISceneTemplatePipelineを実装したクラスを作成します。

using UnityEditor.SceneTemplate;
using UnityEngine;
using UnityEngine.SceneManagement;

public class ExampleTemplatePipeline : ISceneTemplatePipeline
{
    // 有効なテンプレートかどうかを返す
    public bool IsValidTemplateForInstantiation(SceneTemplateAsset sceneTemplateAsset)
    {
        Debug.Log($"{nameof(IsValidTemplateForInstantiation)} - sceneTemplateAsset: {sceneTemplateAsset.name}");
        return true;
    }

    // テンプレートからシーンが作成される前のコールバック
    public void BeforeTemplateInstantiation(SceneTemplateAsset sceneTemplateAsset, bool isAdditive, string sceneName)
    {
        Debug.Log($"{nameof(BeforeTemplateInstantiation)} - isAdditive: {isAdditive} sceneName: {sceneName}");
    }

    // テンプレートからシーンが作成された後のコールバック
    public void AfterTemplateInstantiation(SceneTemplateAsset sceneTemplateAsset, Scene scene, bool isAdditive, string sceneName)
    {
        Debug.Log($"{nameof(AfterTemplateInstantiation)} - scene: {scene} isAdditive: {isAdditive} sceneName: {sceneName}");
    }
}

クラスを作ったらテンプレートのInspectorのScene Template Pipelineにスクリプトアサインします。

Inspector

これで、このテンプレートを使ってシーンが作成される際にスクリプトに書かれた処理が行われるようになります。

スクリプトからシーンテンプレートを操作する

SceneTemplateServiceを使うと、スクリプトからシーンテンプレートを操作することができます。
具体的には以下のように行います。

using UnityEditor;
using UnityEditor.SceneTemplate;
using UnityEngine;

public class Example : MonoBehaviour
{
    private const string SourceScenePath = "Assets/SceneTemplate/ExampleScene01.unity";
    private const string TemplatePath = "Assets/ExampleScene01Template.scenetemplate";
    
    [MenuItem("Example/CreateTemplateFromScene")]
    private static void CreateTemplateFromScene()
    {
        // シーンからテンプレートアセットを作成する
        var sceneAsset = AssetDatabase.LoadAssetAtPath<SceneAsset>(SourceScenePath);
        SceneTemplateService.CreateTemplateFromScene(sceneAsset, TemplatePath);
    }

    [MenuItem("Example/Instantiate")]
    private static void Instantiate()
    {
        // テンプレートアセットからシーンを作成する
        var sceneTemplateAsset = AssetDatabase.LoadAssetAtPath<SceneTemplateAsset>(TemplatePath);
        SceneTemplateService.Instantiate(sceneTemplateAsset, false);
    }
}

参考

docs.unity3d.com