Table of Contents

GlobalObjectId

Every object in the Editor has a distinct GlobalObjectId. This is (effectively) the identifier Unity uses to hold references to other objects. It is guaranteed to be unique and stable between editor sessions.

GlobalObjectIds are not available at runtime. However, they are available in Play Mode in the editor. If you use these in play mode, keep in mind the notes on prefabs below.

Prefabs have two GlobalObjectIds

All notes below only apply to running the game in Play mode in the Editor.

When a scene is loaded in play mode, prefabs are unpacked 1) into standard game-objects. These gameobjects have a different GID than the original prefab. However the GID of the unpacked GameObjects is *still* unique and stable!

For example. You may have a prefab in the scene with GID:

GlobalObjectId_V1-2-78f49d9837f92464f873c69e2450c95f-836954991822709794-4007442380980499986

after unpacking (either by scene load or using PrefabUtility), it will generate a GameObject with GID:

GlobalObjectId_V1-2-78f49d9837f92464f873c69e2450c95f-4323523526593417776-0

Note how the zero at the end of the second GID implies the object is no longer a prefab, which is correct. I call these two GlobalObjectIds the 'Prefab GlobalObjectId' and the 'Unpacked GlobalObjectId'.

Converting a Prefab Gid to an Unpacked Gid

You can convert between the two using the following formula:2)

(prefabGid.targetObjectId ^ prefabGid.targetPrefabId) & 0x7fffffffffffffff

Example Code

Bug: Querying deleted objects

When calling GlobalObjectId.GlobalObjectIdentifiersToObjectsSlow with a GlobalObjectId that was assigned to a now-deleted object, the Object returned will sometimes be a valid, arbitrary Object in the project, rather than the correct value of null.

For example, in this case, when passed an array of only scene objects:

The function will return non-scene objects (the shader editor asset at 205).

This seems to be a bug. The correct result should have been null, because that GID was deleted.

I have had some luck [dark magic] querying these 'bad' GIDs individually with GlobalObjectIdentifierToObjectSlow. This seems to properly return null in certain cases. This does not cure all cases, however3).

Update: This is fixed in 2021.1 bug tracker.

1)
I've seen this mentioned in the profiler as Prefabs.MergePrefabs, during SceneManager scene loads.
2)
Source: https://forum.unity.com/threads/how-is-fileid-generated-for-m_correspondingsourceobject.726704/#post-4851011 This is for a slightly different situation, but I have found that the same formula applies to unpacking prefabs
3)
Luckily, there was only a small set of objects that were valid to be stored by my GIDs, and so I could discard any GIDs resolving to the wrong type.