How do I properly duplicate an object in a editor script?

Hi.

I am writing an editor script that lets you duplicate what you have selected around even easier than with ctrl+d.

But when I use the following code on a barrel I get “barrel(Clone)” as a result and the newly created object is not a prefab.

GameObject go = Object.Instantiate(transform.gameObject, transform.position, transform.rotation) as GameObject;

What I am basically after is the exact code behind the ctrl+d functionality in the Unity editor.

Or if you really want recreate the way the Editor duplicates things try this (Unity 3.5).

[MenuItem("Extra/Duplicate Selected")]
	public static void DuplicateSelected ()
	{
	    Object prefabRoot = PrefabUtility.GetPrefabParent (Selection.activeGameObject);
		
		if (prefabRoot != null)
	    	PrefabUtility.InstantiatePrefab (prefabRoot);
		else
			Instantiate (Selection.activeGameObject);
	}

This will do the same as pressing ctrl + d

[MenuItem("Extra/Duplicate Selected Prefab")]
public static void DuplicateSelectedPrefab()
{
    Object prefabRoot = EditorUtility.GetPrefabParent(Selection.activeGameObject);
    EditorUtility.InstantiatePrefab(prefabRoot);
}

Updating because GetPrefabParent has been deprecated around 2019.1 (plus some extra functionality)

This works on the scene view only - if you want to duplicate in the project (ie. assets) see Ben Blaut’s comment

        // Map it to Alt + D
        [UnityEditor.MenuItem("GaneObject/Duplicate &D", false, 0)]
        public static void Duplicate()
        {
            List<UnityEngine.Object> clones = new List<UnityEngine.Object>();

            foreach (GameObject o in Selection.gameObjects)
            {
                if (!o.transform) continue; // Scene view
                GameObject clone;

                GameObject prefab = PrefabUtility.GetCorrespondingObjectFromSource(o);
                if (prefab != null)
                    clone = PrefabUtility.InstantiatePrefab(prefab, o.transform.parent) as GameObject;
                else
                    clone = UnityEngine.Object.Instantiate(o, o.transform.parent);

                if (clone == null) continue;

                // Do any operations you want on to the cloned object (otherwise this function behaves just like Ctrl+D
                // <---- CUSTOM LOGIC BEGIN ----> 

                // ie. If you want to randomize scale / rotation you can do so here
                // clone.transform.localScale = ;
                // clone.transform.rotation = ;

                // <---- CUSTOM LOGIC END ----> 

                clones.Add(clone);

                // Register the duplicated objects to be able to undo
                Undo.RegisterCreatedObjectUndo(clone, "Duplicate");
            }

            if (clones.Count == 0) return;

            // Select the duplicated objects
            Selection.objects = clones.ToArray();
        }