Метод заменяет сборный объект существующими объектами, но в некоторых ситуациях он делает это неправильно.
Например, когда у меня в Иерархии есть родительский объект и два дочерних объекта:
Cube
Cube1
Cube2
Если я заменю Cube на префаб, он удалит Cube, Cube1, Cube2 и создаст новый префаб.
Но я хочу, чтобы он заменил только куб на префаб и сохранил дочерние элементы Cube1 и Cube2 такими, какие они есть и как дочерние элементы Cube.
И если, например, я выберу Cube и Cube2, то заменим Cube и Cube2, но оставим родительский и дочерний элементы такими, какие они есть:
Prefab
Cube1
Prefab
или
Prefab
Prefab
Prefab
Идея состоит в том, чтобы сохранить структуру parent / childs.
Метод:
private void InstantiatePrefab(List<GameObject> selection)
{
if (prefab != null && selection.Count > 0)
{
for (var i = selection.Count - 1; i >= 0; --i)
{
var selected = selection[i];
SceneManager.SetActiveScene(SceneManager.GetSceneByName(selected.scene.name));
var prefabType = PrefabUtility.GetPrefabType(prefab);
GameObject newObject;
if (prefabType == PrefabType.Prefab)
{
newObject = (GameObject)PrefabUtility.InstantiatePrefab(prefab);
}
else
{
newObject = Instantiate(prefab);
newObject.name = prefab.name;
}
if (newObject == null)
{
Debug.LogError("Error instantiating prefab");
break;
}
Undo.RegisterCreatedObjectUndo(newObject, "Replace With Prefabs");
newObject.transform.parent = selected.transform.parent;
newObject.transform.localPosition = selected.transform.localPosition;
newObject.transform.localRotation = selected.transform.localRotation;
newObject.transform.localScale = selected.transform.localScale;
newObject.transform.SetSiblingIndex(selected.transform.GetSiblingIndex());
Undo.DestroyObjectImmediate(selected);
}
}
}
Использование:
void OnGUI()
{
var selection = Selection.objects.OfType<GameObject>().ToList();
InstantiatePrefab(selection);
}