1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Unityでヒエラルキーのオブジェクト全てのActive状態を保存・再生するエディタ拡張

Last updated at Posted at 2025-05-16

表題の通りです。

1. 概要

UnityのScene内に存在するすべてのGameObjectの表示状態(activeSelf)を保存し、あとから復元できるエディタ拡張ツールです。

  • SnapShotボタン:現在の表示状態を保存
  • Resumeボタン:保存された状態を復元
  • Unityの再起動後は instanceID が無効になるため、名前階層(path)で探索し復元
    (一度復元したあとは自動で SnapShot を再保存し、次回からは高速に復元可能)

2. スクリプト本体

Assets/Editor/VisibilitySnapshot.cs に以下のコードを配置してください:

VisibilitySnapShot
using UnityEngine;
using UnityEditor;
using System.Collections.Generic;
using System.IO;


/// <summary>
/// Unityでヒエラルキーのオブジェクト全てのActive状態を保存・再生するエディタ拡張
/// </summary>
/// instanceIDが無くなった時だけパスでFindする。それ以外はinstanceIDで取得する。
public class VisibilitySnapshot : EditorWindow
{
    private const string FILE_PATH = "Library/VisibilitySnapshot.json";

    [System.Serializable]
    private class Entry
    {
        public int id;
        public string path;
        public bool active;
    }

    [System.Serializable]
    private class EntryList
    {
        public List<Entry> entries = new List<Entry>();
    }

    [MenuItem("Tools/Visibility Snapshot")]
    public static void ShowWindow()
    {
        GetWindow<VisibilitySnapshot>("Visibility Snapshot");
    }

    private void OnGUI()
    {
        if (GUILayout.Button("SnapShot (Save to File)"))
        {
            SaveSnapshotToFile();
        }

        if (GUILayout.Button("Resume (Load from File)"))
        {
            LoadSnapshotFromFile();
        }
    }

    private void SaveSnapshotToFile(bool _showMsg = true)
    {
        var list = new EntryList();
        foreach (GameObject root in GetAllRootGameObjectsInScene())
        {
            RecordRecursive(root, "", list.entries);
        }

        string json = JsonUtility.ToJson(list, true);
        File.WriteAllText(FILE_PATH, json);
        Debug.Log($"スナップショットを保存しました ({list.entries.Count}件): {FILE_PATH}");

        if (_showMsg)
        {
            EditorUtility.DisplayDialog("SnapShot完了", $"スナップショットを保存しました\n({list.entries.Count}件)", "OK");
        }
    }

    private void LoadSnapshotFromFile()
    {
        if (!File.Exists(FILE_PATH))
        {
            Debug.LogWarning("スナップショットファイルが見つかりません。");
            return;
        }

        string json = File.ReadAllText(FILE_PATH);
        var list = JsonUtility.FromJson<EntryList>(json);
        int changed = 0;

        bool foundPath = false;
        foreach (var entry in list.entries)
        {
            GameObject obj = EditorUtility.InstanceIDToObject(entry.id) as GameObject;

            if (obj == null)
            {
                // IDが無効なら、パスで探す
                obj = GameObject.Find(entry.path);
                foundPath = true;
            }

            if (obj != null && obj.activeSelf != entry.active)
            {
                obj.SetActive(entry.active);
                changed++;
            }
        }

        Debug.Log($"スナップショットを復元しました ({changed}件)");

        // 復元したオブジェクトの中に、パスで見つけたものがあった場合は、次の高速化のために再度保存しておく
        if (foundPath)
        {
            SaveSnapshotToFile(false); 
        }
    }

    private void RecordRecursive(GameObject obj, string parentPath, List<Entry> entries)
    {
        string path = string.IsNullOrEmpty(parentPath) ? obj.name : parentPath + "/" + obj.name;

        entries.Add(new Entry
        {
            id = obj.GetInstanceID(),
            path = path,
            active = obj.activeSelf
        });

        foreach (Transform child in obj.transform)
        {
            RecordRecursive(child.gameObject, path, entries);
        }
    }

    private GameObject[] GetAllRootGameObjectsInScene()
    {
        var scene = UnityEngine.SceneManagement.SceneManager.GetActiveScene();
        return scene.GetRootGameObjects();
    }
}

3. 導入手順

1.Unityエディタで Assets/Editor/ フォルダを作成(なければ)
2.下記スクリプトを作成:VisibilitySnapshot.cs

4. 使い方

① スナップショットの保存

Unity上部メニューから
 Tools > Visibility Snapshot をクリック

表示されたウィンドウで
「SnapShot (Save to File)」をクリック

現在のScene内にあるすべてのGameObjectの「表示状態(activeSelf)」を記録します。
◆保存先ファイル:/Library/VisibilitySnapshot.json に出力されます。

② スナップショットの復元

再び Tools > Visibility Snapshot ウィンドウを開く
「Resume (Load from File)」をクリック

保存時と同じScene内であれば、
 - InstanceIDベースで高速復元
 - 見つからない場合は GameObjectの名前階層(Root/Child/...)で復元
  (その場合次の高速化に備えてSaveも行う)

Sceneを再起動してもファイルが残っていれば復元可能です。

5. メリットと注意点

  • Unityセッション中は高速
  • 再起動後の初回復元は GameObject.Find() になるので少し遅い
  • ただし一度復元すれば、以後は再び instanceID を利用して高速化
1
1
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
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?