LoginSignup
129
135

More than 5 years have passed since last update.

[Unity] Sceneの役割や使い方をざっくりまとめた

Last updated at Posted at 2016-09-16

Unity触る上で避けては通れないのでざっくり書いた

Sceneとは?

SceneをUnityEditor上で作る

  • Pojectビュー上の[create]ボタン (もしくは右クリック > Create) からSceneを選択
  • もしくは上部メニューより [Edit] => [NewScene] を選択で新規Sceneが読み込まれる
    • [Ctrl(Cmd) + n] がショートカット

SceneをUnityEditor上で読み込む

  • Project上での任意のSceneファイルをダブルクリック
    • 現在Hierarchy上で開かれているSceneは閉じられる(アンロードされる)ので注意
    • 複数のSceneを読み込んでいる場合、全て閉じられるので注意
  • 複数のSceneを同時に読み込みたい場合は任意のSceneファイルをHierarchy上にドラッグ&ドロップ

addscene.gif
(実際はCameraを破棄されないGameObjectとして複数混在させないほうが良いがDEMO用に...)

SceneをUnityEditor上でアンロードする

  • https://docs.unity3d.com/ja/current/Manual/MultiSceneEditing.html
  • Hierarchy上の任意のシーンを右クリック (もしくはScene名右のメニューを展開)
  • UnloadScene
    • シーンをアンロードされるが、Hierarchy内に表示されたままとなる
    • Editor上で一時的に特定のシーンを無効にしたいときに使用する
  • RemoveScene
    • シーンをアンロードし、Hierarchy上からも消す

unloadscene.gif

Sceneの保存形式をバイナリからテキストに変更する

  • デフォルトではバイナリファイルで保存される
  • この状態でgit等でバージョン管理した際にコンフリクトすると解消が困難
    • (テキストに切り替えても仕様ベースの問題で解消困難なケースは多々あるけど....)
  • 設定からテキスト(YAML形式)として保存するようにしておくことをオススメ

変更方法

  • [Edit] => [Project Settings] => [Editor] でEditorSettingsを表示
  • AssetSerializationForceText に変更

forcetext.png

BuildSettingsにSceneを定義する

  • https://docs.unity3d.com/jp/current/Manual/BuildSettings.html
  • 上部メニューより [File] => [BuildSettings...] を開く
  • 上部の Scenes in Build にSceneを登録しないと実行時に動的に呼び出せないので注意
    • SceneをEditor上で開いた状態で [Add Open Scenes] を選択する
    • Project上のSceneファイルをドラッグ&ドロップする

buildsetting.gif

実行中にScript上からSceneを操作する

SceneManagerについて

using UnityEngine.SceneManagement;

任意のSceneに切り替える

using UnityEngine;
using UnityEngine.SceneManagement;

public class SceneTest : MonoBehaviour
{
    public void MoveScene()
    {
        // 引数にシーン名を指定する
        // Build Settings で確認できる sceneBuildIndex を指定しても良い
        SceneManager.LoadScene("stage1"); 
    }
}

任意のSceneを追加で読み込む

using UnityEngine;
using UnityEngine.SceneManagement;

public class SceneTest : MonoBehaviour
{
    public void AddScene()
    {
        SceneManager.LoadScene("stage2", LoadSceneMode.Additive); 
    }
}

任意のSceneを非同期に読み込む

using UnityEngine;
using UnityEngine.SceneManagement;

public class SceneTest : MonoBehaviour
{
    public void AddSceneAsync()
    {
        SceneManager.LoadSceneAsync("stage3", LoadSceneMode.Additive); 
    }
}

任意のSceneをアンロードする

using UnityEngine;
using UnityEngine.SceneManagement;

public class SceneTest : MonoBehaviour
{
    public void RemoveScene()
    {
        // 引数にシーン名を指定する
        // Build Settings で確認できる sceneBuildIndex を指定しても良い
        SceneManager.UnloadScene("stage1"); 
    }
}

現在読み込まれているSceneの名称をリストで取得する

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

public static class SceneUtil
{
    public static List<string> GetActiveSceneNames()
    {
        int sceneCount = SceneManager.sceneCount;
        List<string> activeSceneNames = new List<string>();
        for (int i = 0; i < sceneCount; i++)
        {
            Scene scene = SceneManager.GetSceneAt(i);
            activeSceneNames.Add(scene.name);
        }
        return activeSceneNames;
    }
}
using UnityEngine;
using UnityEngine.SceneManagement;
using System.Collections.Generic;

public class SceneTest : MonoBehaviour
{
    public void ShowActiveSceneNames()
    {
        foreach (string name in SceneUtil.GetActiveSceneNames())
        {
            Debug.Log(name);
        }
    }
}

現在のシーンをアンロードし、指定したScene群を読み込む

  • もっと綺麗に書ける気がするけどざっくり
using UnityEngine.SceneManagement;
using System.Collections.Generic;
using System.Linq;

public static class SceneUtil
{
    public static void MoveScenes(List<string> sceneNames)
    {
        List<string> activeSceneNames = GetActiveSceneNames();
        Dictionary<string, bool> activeSceneNameMap = activeSceneNames.ToDictionary(name => name, name => true);
        Dictionary<string, bool> sceneNameMap = sceneNames.ToDictionary(name => name, name => true);

        // シーンのロード
        // シーンが空にならないように先に行う
        // 既に読み込まれている場合、そのまま利用する
        foreach (string sceneName in sceneNames)
        {
             if (!activeSceneNameMap.ContainsKey(sceneName))
             {
                 SceneManager.LoadScene(sceneName, LoadSceneMode.Additive);
             }
        }

        // シーンのアンロード
        // 読み込むシーンに指定されている場合はアンロードしない
        foreach (string activeSceneName in activeSceneNames)
        {
             if (!sceneNameMap.ContainsKey(activeSceneName))
             {
                 SceneManager.UnloadScene(activeSceneName);
             }
        }
    }

    public static List<string> GetActiveSceneNames()
    {
        int sceneCount = SceneManager.sceneCount;
        List<string> activeSceneNames = new List<string>();
        for (int i = 0; i < sceneCount; i++)
        {
            Scene scene = SceneManager.GetSceneAt(i);
            activeSceneNames.Add(scene.name);
        }
        return activeSceneNames;
    }
}
using UnityEngine;
using UnityEngine.SceneManagement;
using System.Collections.Generic;

public class SceneTest : MonoBehaviour
{
    public void MoveScenes()
    {
        List<string> sceneNames = new List<string>() { "stage1", "stage2", "stage3" };
        SceneUtil.MoveScenes(sceneNames);
    }
}

Sceneを跨いで使用するGameObjectを用意する

Editor拡張でSceneを取り扱う

例) 全てのシーンのTextComponentを指定したフォントに置き換える君

129
135
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
129
135