シーンに配置されているもの一覧
開発中のデバッグにおいて、今のシーンに配置されているGameObject
の一覧を取得したいことがあります。
UnityEditor
上でならばHierarchy
上にあるものを見れば済むわけですが、やっぱり実機上で何が起こっているのかを知りたいわけです。
このとき、普通のシーン上に配置されているものなら以下のコードで取得できます。
// 現在のHierarchyのRootにあるGameObjectの一覧
var currentSceneGameObjects = SceneManager.GetActiveScene().GetRootGameObjects();
DontDestroyOnLoadの一覧
普通のやつはそれでいいのですが、DontDestroyOnLoad
に登録されたGameObject
を取得するAPIはありません。
実機でしか動作しないSDKが動的にテキトーに作成するGameObject
や、タイミングによって実機でしか起きない事象などを解析する場合など、どうしても実機上でDontDestroyOnLoad
の一覧が取りたい場合があります。
というわけで、以下のような回避策で取得することができました。
// まずDontDestroyOnLoadされたGameObjectを作る
var go = new GameObject(string.Empty);
Object.DontDestroyOnLoad(go);
// DontDestroyOnLoadはSceneの一種なので,GameObject.sceneから取得することができる
var dontDestroyOnLoadGameObjects = go.scene.GetRootGameObjects();
解析用コード
これを利用してこんな解析用のコードを作ってみました。
このファイルをプロジェクトに入れておくだけで、シーン遷移のたびに、シーン名と合わせてDontDestroyOnLoad
の一覧をログに出力してくれます。
CollectDontDestroyOnLoad()
をpublic
にしておいたので、好きなときにGameObject
の配列を取得することもできます。
using System.Linq;
using UnityEngine;
using UnityEngine.SceneManagement;
namespace Nekomimi.Daimao
{
public class DontDestroyOnLoadCollector
{
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
private static void Register()
{
SceneManager.sceneLoaded += (scene, mode) =>
{
var ddol = CollectDontDestroyOnLoad();
var separator = ", ";
var s = string.Join(separator, ddol.Where(go => go != null).Select(go => go.name));
Debug.Log($"DDOL_{scene.name} : {s}");
};
}
public static GameObject[] CollectDontDestroyOnLoad()
{
var go = new GameObject(string.Empty);
Object.DontDestroyOnLoad(go);
var ddol = go.scene.GetRootGameObjects();
Object.Destroy(go);
return ddol.Where(o => o != null && !string.Equals(o.name, string.Empty)).ToArray();
}
}
}
実機での動作について
How can I get all DontDestroyOnLoad GameObjects?
ここの解答をもとに作ったのですが、Editorでしか動かないことが強調されています。
works only in the Editor
また、その根拠として示されている公式ドキュメントでも以下のような記載があります。
You do not have access to the DontDestroyOnLoad scene and it is not available at runtime.
でも私が試したところではAndroid
でもiOS
でも実機にブッこんだら動きました!
UnityEditor
のバージョンは2018と2019です。下のバージョンは覚えてない。
Android
とiOS
でしか試してませんが、この分だと他のプラットフォームでも動きそうな気がします。
公式ができねえ! と言ってることをやってるので、使用範囲はあくまでもデバッグにとどめたほうがよいとは思いますが。
まとめ
先人の解答を参考にしつつも、とりあえず自分で数発殴ってみることは重要だなって思いました。
あと普通に考えて公式がそういうAPI用意してくれてもよくない……? って! 思いました!
DontDestroyOnLoad
って状態の権化みたいなものなのでできるだけ使わないのがベストプラクティスな気もしますが。でも使っちゃうね。しょうがないね。
おしまい。