Is there a way to tell when a prefab is duplicated?

I have created a component which generates a GUID which allows me to know what prefab a GameObject instance came from, but when a prefab is duplicated the new prefab simply use the same id as the previous one (which is to be expected). So I would like to know if there is a way to detect when prefabs and objects in general are duplicated so that I can generate a new id.

public class GUID : MonoBehaviour 
{
	public string idString = System.Guid.NewGuid().ToString("N");

	private System.Guid _id;
	public System.Guid ID
	{
		get 
		{
			if (_id == System.Guid.Empty && !string.IsNullOrEmpty(idString))
			{
				_id = new System.Guid(idString);
			}
			return _id;
		}
	}
}

[CustomEditor(typeof(GUID))]
public class GUIDInspector : Editor 
{
	public override void OnInspectorGUI()
	{
		GUID guid = target as GUID;
		GUILayout.Label("ID: " + guid.ID.ToString("N"));
		GUILayout.Label("ST: " + guid.idString);
	}
}

Some more info on why I need this.
This will be part of a system where I need to keep a player inventory/bag and know what prefab to spawn if he drops something form the bag. When a player pick up an item I simply save the GUID to the list of items in the bag while I remove the original GameObject from the world. I have a GameObject in the scene which carry a reference to all the item prefabs so that I can simply use that to find the prefab I want to instantiate. Later I need to expand on this idea to also work for a game save/load system and will have to generate unique IDs for objects in the scene too.

Every prefab copied somewhere is bound to either have a different name, time stamp or time stamped meta file produced by unity.

Is it not possible to combine your GUID along with an md5 hash of prefab name + time stamp information extracted from the prefab, meta file or perhaps both and use this as your new identifier?

Thinking about this, filename and path MD5’d should work too.

If i got your right you just need this at edit time to give each prefab a unique ID. In this case you can try using the “quite new” AssetModificationProcessor.

This works for me:

//C#
using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Collections.Generic;

public class DetectDuplicates : AssetModificationProcessor
{
	public static List<string> newAssets = new List<string>();
	static void OnWillCreateAsset(string aMetaAssetPath)
	{
		string assetPath = aMetaAssetPath.Substring(0,aMetaAssetPath.Length-5);
		newAssets.Add(assetPath);
	}
}

class DetectDuplicatesPostprocessor : AssetPostprocessor
{
	static void OnPostprocessAllAssets(string[] importedAssets,string[] deletedAssets,string[] movedAssets,string[] movedFromAssetPaths)
	{
		if (DetectDuplicates.newAssets.Count == 0)
			return;
		foreach (var str in importedAssets)
		{
			if (DetectDuplicates.newAssets.Contains(str))
			{
				GameObject obj = AssetDatabase.LoadAssetAtPath(str,typeof(GameObject)) as GameObject;
				if (obj == null)
					continue;
				var comp = obj.GetComponent<YourPrefabComponent>();
				if (comp == null)
					continue;
				comp.GenerateNewPrefabID();
			}
		}
		DetectDuplicates.newAssets.Clear();
	}
}

In my sample the component attached to the prefab is named “YourPrefabComponent” and it has a public function called GenerateNewPrefabID. This Postprocessor will execute this function if the asset it newly created.

How it works:

The AssetModificationProcessor gets informed when Unity will create a new meta file (for a new asset). I just strip the .meta and save the filename as “new asset” in a List.

When the asset is finally created and imported the AssetPostprocessor will take care of “postprocessing” the actual asset if it’s in the list.