5
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

[Unity Editor拡張] File IDの取得、シーン上のローカルIDの取得

Last updated at Posted at 2021-04-27

##File IDとは?
UnityのアセットはGuidで管理されています。SceneやPrefab内(Hierarchy上)ではFile IDで管理されています。

samle.unity
--- !u!4 &1781688880
Transform:
  m_GameObject: {fileID: 1781688879}

##2019.2以降でのFile IDの取得
GlobalObjectIdを使うと楽です。もちろんエディタ上でしか動作しません。

UnityEngine.Object targetObject = Selection.activeObject;
// GlobalObjectIdに変換
var id = GlobalObjectId.GetGlobalObjectIdSlow(targetObject);
// File ID
id.targetObjectId
// PrefabならInstance IDが入る Prefabで無ければ0
id.targetPrefabId

// GUID Prefabなら参照元(親)のGuidがIDが入る
id.assetGUID
// アセットの種別 0 = Null, 1 = Imported Asset, 2 = Scene Object, 3 = Source Asset
id.identifierType

シリアライズ、デシリアライズ

シリアライズ

ToString()がオーバーライドされていてGlobalObjectIdを文字列にしてくれるので便利。Editor拡張に優しいですね。

下記のようなフォーマットで出力されます。
GlobalObjectId_V1-{identifierType}-{assetGUID}-{targetObjectId}-{targetPrefabId}
デフォルト
GlobalObjectId_V1-0-00000000000000000000000000000000-0-0

var id = GlobalObjectId.GetGlobalObjectIdSlow(targetObject);
var idString = id.ToString();
Debug.Log(idString);
// [Console] GlobalObjectId_V1-x-x-x-x

デシリアライズ

上記で言うidStringTryParseにそのまま突っ込むだけでOK。便利

if (GlobalObjectId.TryParse(idString, out GlobalObjectId result))
{
    switch (result.identifierType)
    {
        // プロジェクト内のアセッは簡単
        case 1:
            var obj = GlobalObjectId.GlobalObjectIdentifierToObjectSlow(result);
            Debug.Log(obj.name);
            break;

        // シーン上のアセットは取得が面倒だし重い
        case 2 :
            // 多分、シーンが開いていないと取得できません。
            // 1. シーン上のすべてのgameObjectをGlobalObjectIdに変換
            var sceneObjects = GameObject.FindObjectsOfType<GameObject>();
            var sceneObjectIds = new GlobalObjectId[sceneObjects.Length];
            GlobalObjectId.GetGlobalObjectIdsSlow(sceneObjects, sceneObjectIds);

            // 2. 一致するものを探す
            for (var i = 0; i < sceneObjectIds.Length; i++)
            {
                if (sceneObjectIds[i].Equals(result))
                {
                    Debug.Log(sceneObjects[i].name);
                    break;
                }
            }
            break;
    }
}

##2019.2未満でのFile IDの取得
取得できるだけありがたいですが、触れてはいけない部分から取得してる気がして若干怖いです。
m_LocalIdentfierInFileがスペルミスしてるので気をつけてください。

var inspectorModeInfo = typeof(SerializedObject).GetProperty("inspectorMode", BindingFlags.NonPublic | BindingFlags.Instance);
var serializedObject = new SerializedObject(Selection.activeObject);
inspectorModeInfo.SetValue(serializedObject, InspectorMode.Debug, null);
var localIdProp = serializedObject.FindProperty("m_LocalIdentfierInFile");

//File ID
Debug.Log(localIdProp.intValue);

参考

How to get the Local Identifier In File for scene objects - Unity Foru

5
3
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
5
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?