Is there a way to compare object instances?

Is there’s a way to check if the instance is a clone:

var obj1 = new GameObject("Test");
var obj2 = Instantiate(obj1);

if(obj1 'is  copy of' obj2)
    // Do something...

As far as I’ve read both are independent copies with different IDs.
One way would be to have a common reference in both.

Not fundamentally, but you can compare any number of aspects about them to see if they’re the same. If you know (based on your game/code) what could change, you can check for that.

If your object has a script of a particular type on it, you could do this:

public int uniqueID = -1;
public static int currentUniqueID = 0;

void Awake() {
if (uniqueID < 0) {
uniqueID = currentUniqueID;
currentUniqueID++;
}
}

Now you can compare the two objects’ uniqueID values. If they’re the same, then one was cloned from the other one.

To expand on StarManta’s post.

The first option of if they have similar aspects doesn’t necessarily mean one was cloned from another. Only that those aspects are similar. Go with this route if you’re attempting to determine if things are “similar”.

The second option will let you know if one was cloned from another, but it doesn’t mean they’re similar, since once cloned you may have modified the clone. If you’re only trying to test from what something originated, use that.

What your end goal is will determine which you need.

Also, expanding on option 2, I’d probably encapsulate this functionality into its own script to keep its logic distinct from other stuff. Also why not just store a ref to the source object for easy access. Something like this:

public class TrackedClone : MonoBehaviour
{
    private GameObject _source;
    public GameObject Source { get { return _source; } }

    public static GameObject InstantiateTrackedClone(GameObject source)
    {
        var clone = Instantiate(source);
        var token = clone.GetComponent<TrackedClone>(); //incase the go already has it
        if (token == null) token = clone.AddComponent<TrackedClone>();
        token._source = source;
        return clone;
    }

    public bool CameFromSource(GameObject obj, GameObject sourceToTest)
    {
        var token = obj.GetComponent<TrackedClone>();
        return token != null && token._source == sourceToTest;
    }

}

But yeah, outside of coming up with your own approach, there is no built in way of tracking this.

1 Like

Probably a good idea, but if we’re going that far, we could remove the InstantiateTrackedClone function and use the logic from my code to find the original to allow clones to figure out for themselves upon instantiation who they’re cloned from:
(I have no idea if this is helpful to OP any more, it’s mostly just a fun exercise)

public class SelfTrackingClone : MonoBehaviour
{
   public int uniqueID = -1;
   public static int currentUniqueID = 0;
   private static Dictionary<int, SelfTrackingClone> all = new Dictionary<int, SelfTrackingClone>();

   public SelfTrackingClone clonedFrom = null;
   public bool wasAClone = false;
   void Awake() {
      if (uniqueID >= 0) {
         clonedFrom = all[uniqueID];
         wasAClone = true; // Can't just do "clonedFrom != null" because clonedFrom could get destroyed
      }
      uniqueID = currentUniqueID;
      currentUniqueID++;
   }
}

So with this version, uniqueID will actually always be unique per object, but you can check clonedFrom against the other object reference to see if it’s a clone of it.

1 Like

Hey guys, thank you for your answers both are interesting, I’ll use a GUID for the source object, basically what StarManta proposed.

True, but this is just inversion of how it gets tracked.

In yours you need to stick the component on the OG object, and then from there it is always copied.

Where as with mine, the instantiating will add the necessary component if it didn’t already exist.

I guess the ‘combination’ would be take mine, and stick this logic in it, so it covers both cases.