Unity has a very annoying issue that duplicate object will put your new duplicates at bottom of hierarchy
So, here I found a code in this forum post to solve this issue, and I rewrite asset duplicate part and renew some legacy function This tool really saved my life especially I used to sort my hierarchy with different usage
<aside> 💡 See also [Tool] Color Hierarchy Highlighter to make better sorting of your hierarchy
</aside>
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
public static class EditorDuplicateCommand
{
[MenuItem("Edit/Smart Duplicate %d", false, 0)]
private static void DuplicateSelection()
{
var newSelection = new List<Object>();
if (Selection.gameObjects.Length > 0)
{
for (int ui = 0; ui < Selection.gameObjects.Length; ui++)
{
var go = Selection.gameObjects[ui];
int siblingIndex = go.transform.GetSiblingIndex();
var newGo = SmartInstantiate(go);
newGo.transform.parent = go.transform.parent;
newGo.transform.position = go.transform.position;
newGo.transform.SetSiblingIndex(siblingIndex + 1);
newGo.name = go.name;
newSelection.Add(newGo);
}
}
else
{
for (int ui = 0; ui < Selection.objects.Length; ui++)
{
var go = Selection.objects[ui];
var newGo = DuplicateAsset(go);
newSelection.Add(newGo);
}
}
Selection.objects = newSelection.ToArray();
}
private static GameObject SmartInstantiate(GameObject go)
{
if (PrefabUtility.GetPrefabInstanceStatus(go) == PrefabInstanceStatus.Connected)
{
var prefab = PrefabUtility.GetCorrespondingObjectFromSource(go) as GameObject;
var newGo = (GameObject)PrefabUtility.InstantiatePrefab(prefab);
var mods = PrefabUtility.GetPropertyModifications(go);
PrefabUtility.SetPropertyModifications(newGo, mods);
return newGo;
}
if (PrefabUtility.GetPrefabAssetType(go) != PrefabAssetType.NotAPrefab)
{
return DuplicateAsset(go) as GameObject;
}
return GameObject.Instantiate(go) as GameObject;
}
private static Object DuplicateAsset(Object targetAsset)
{
int index = 1;
while (AssetDatabase.LoadAssetAtPath<Object>(AssetDatabase.GetAssetPath(targetAsset).Replace(".", " " + index + ".")) != null)
{
index++;
if (index > 100)
{
Debug.LogError("Massive Asset Duplicate Detect");
}
}
AssetDatabase.CopyAsset(AssetDatabase.GetAssetPath(targetAsset), AssetDatabase.GetAssetPath(targetAsset).Replace(".", " " + index + "."));
return AssetDatabase.LoadAssetAtPath<Object>(AssetDatabase.GetAssetPath(targetAsset).Replace(".", " " + index + "."));
}
}
Create this code
Press Ctrl+D and Unity will show this shortcut conflict window, chose Resolve Conflict
Shortcuts window will opened automatically (you can also find it in Edit→Shortcuts ) Remove one of them and move to other shortcut like Ctrl+Shift+D (I suggest keep native duplicate since current code still have few issue when duplicating non GameObject target)
Enjoy new duplicate experience!
<aside> 💡 If you want to change back default Duplicate, just go to Shortcuts Window and assign Duplicate function back
</aside>
If you like my article, follow my [**Twitter**](<https://twitter.com/FrogskinShen>) or buy me a coffee to support my creation!
如果你喜歡我的文章,可以跟隨我的[**Twitter**](<https://twitter.com/FrogskinShen>)或請我喝杯咖啡來支持我 😀
Check Main Page for More Article
來主頁看看更多文章
[Froggy's Game Making Note](<https://frogskinnn.notion.site/Froggy-s-Game-Making-Note-3efe78e21eab4034a8af14fcdbde6a30>)