该方法确实用现有对象替换了预制件,但是在某些情况下,这样做是不正确的。
例如,当我在层次结构中有一个父对象和两个孩子时:
Cube
Cube1
Cube2
如果我将Cube替换为预制件,它将删除Cube,Cube1,Cube2并创建新的预制件。
但是我希望它仅用预制件替换Cube,并保持子Cube1和Cube2的原样以及作为Cube的子代。
例如,如果我选择“多维数据集”和“多维数据集2”,然后替换“多维数据集”和“多维数据集2”,但将父级和子级保持不变:
Prefab
Cube1
Prefab
或
Prefab
Prefab
Prefab
想法是保留父子结构。
方法:
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);
}