なつねこメモ

主にプログラミング関連のメモ帳 ♪(✿╹ヮ╹)ノ 書いてあるコードは自己責任でご自由にどうぞ。記事本文の無断転載は禁止です。

Unity で File (Local) ID を元に Object を検索したい

まあ普通にやっていてそんなケースは無いと思うのですが、以下の場合。

  • Unity のシーンファイルを解析中
  • YAML のタグ情報は使えない

みたいな場合、 GetComponentsInChildren<T> からがんばって探すことになります。
そういったときのやり方。

まずは、以下のプロパティと関数を定義します。

private static readonly PropertyInfo InspectorMode = typeof(SerializedObject).GetProperty("inspectorMode", BindingFlags.NonPublic | BindingFlags.Instance);

private static long GetLocalIdentifierByObject(Object obj)
{
    var so = new SerializedObject(obj);
    InspectorMode.SetValue(so, UnityEditor.InspectorMode.Debug);

    return so.FindProperty("m_LocalIdentfierInFile").longValue;
}

AssetDatabase#TryGetGUIDAndLocalFileIdentifier も試してみたものの動かないので、
リフレクション経由で取得します。

あとは下のような関数を定義して、

T FullScanObjectInChildrenByFileID<T>(GameObject rootGameObject, long fileId) where T : Object
{
    var objects = rootGameObject.GetComponentsInChildren<T>();
    return objects.Where(w => w != null).FirstOrDefault(w => fileId == GetLocalIdentifierByObject(w));
}

このように使えば、 FileID を元に何らかのオブジェクトを得ることが可能です。

FullScanObjectInChildrenByFileID<SkinnedMeshRenderer>(obj, 1234567890);

ということで、メモでした。

参考: