Search Unity

  1. We are migrating the Unity Forums to Unity Discussions. On July 12, the Unity Forums will become read-only. On July 15, Unity Discussions will become read-only until July 18, when the new design and the migrated forum contents will go live. Read our full announcement for more information and let us know if you have any questions.

Discussion An explanation of how InstanceIDs work

Discussion in 'Scripting' started by MechaWolf99, Jan 27, 2023.

  1. MechaWolf99

    MechaWolf99

    Joined:
    Aug 22, 2017
    Posts:
    296
    During a recent Dev Blitz Day, I was able to ask a dev at Unity about InstanceIDs and how they work, this is just a summery of that information for future reference and those that are interested.

    Instance IDs are based on load order. As objects are loaded into memory they increment a persistent counter. When an object is loaded from disk, it increments a positive 32 bit index, and objects created in memory decrement a negative 32 bit index.

    Instance IDs for objects are track by a 'remapper' which allows them to persist through a session.
    The developer did note in relation to the persistence of instance IDs: "It is very possible there are edge cases to this that I'm not aware of, as the object tracking is quite complex.". So take that as you will.

    From a internal doc:
    "The InstanceID of an object is assigned in-memory and that value is only held stable during the Unity session. E.g. the next time the project is loaded the instance id will very likely be different. If the load order of objects in a standalone player is repeated then an object could get the same object id each time, but that would be a dangerous assumption to rely on."

    On the native side there is a struct called
    SerializedObjectIdentifier
    which is the ID that is written to disk. Instance ID is effectively a stable pointer (If you see
    PPtr
    in some places, that is it is).
    So when an object is loaded the also native
    PersistentManager
    keeps a mapping between the serialized ID and the session instance ID. And is responsible for translating between these two values.

    That is all I got, if anyone has more insight on instance IDs and how they work, please do share!
     
    kubacho-lab and MartinTilo like this.
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    39,571
    My sense of all these IDs is that they are probably "dangerous" to rely upon in your code.

    It's so trivial to tag things with your own identifier that I always do that, when I need it.

    I also NEVER make my own identifier / GUID for assets. I've seen coworkers wrestle endlessly with this stuff, fighting duplication, deconfliction, etc., and it's just never a good idea, IMNSHO.

    Instead I force myself to use unique file names for each asset so that I can unambiguously load them, either in Editor time (AssetDatabase) or Resources.Load<T>();
     
    lordofduct likes this.
  3. chemicalcrux

    chemicalcrux

    Joined:
    Mar 16, 2017
    Posts:
    726
    It's definitely fun to play around with the internals of an engine, though :D
     
    Kurt-Dekker likes this.
  4. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    4,261
    Well, that already summed up most there is to know about them. As the documentation already said and Kurt suggested, you should not really care about the InstanceID as it's an internal implemntation detail and mainly used by the engine itself.

    The instance id is actually more important than what most may think. It's the actual "glue" between the managed and native code part of any tracked UnityEngine.Object in the engine. Yes, there's also the "m_CachedPtr" but when it's not set, the instance ID does establish the actual link between the two sides.
     
    DragonCoder likes this.
  5. halley

    halley

    Joined:
    Aug 26, 2013
    Posts:
    2,661
    This duality probably explains why Duplicates in the Editor go to the bottom of the hierarchy, while dragged Prefabs go to the top. Annoying behavior.

    Yes, the only real purpose of the instance ID is to make inter-references in a single serialized stream, without accidentally making duplicates. You used a material in two objects, it only realizes that it's the same material instance because they both had the same instance ID in the serialized stream. Once it's in memory, it's really not a good idea to make any assumptions or build any information on it. It's like knowing the index of an item inside a Dictionary... easy for implementations to change, or even values to change mid-run for undocumented reasons.