Это код для замены:
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEngine;
public class SaveTransformsInfo : EditorWindow
{
[SerializeField] private GameObject prefab;
[MenuItem("Tools/Replace With Prefab")]
static void CreateReplaceWithPrefab()
{
EditorWindow.GetWindow<SaveTransformsInfo>();
}
private void OnGUI()
{
prefab = (GameObject)EditorGUILayout.ObjectField("Prefab", prefab, typeof(GameObject), false);
if (prefab == null || Selection.gameObjects.Length == 0)
{
GUI.enabled = false;
}
else
{
GUI.enabled = true;
}
if (GUILayout.Button("Replace"))
{
var selection = Selection.gameObjects;
var parentGameobjects = CheckParents(selection);
#if UNITY_EDITOR
UnityEditor.Selection.objects = parentGameobjects;
#endif
for (var i = parentGameobjects.Length - 1; i >= 0; --i)
{
var selected = parentGameobjects[i];
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.position = selected.transform.position;
newObject.transform.rotation = selected.transform.rotation;
newObject.transform.localScale = selected.transform.localScale;
newObject.transform.SetSiblingIndex(selected.transform.GetSiblingIndex());
DestroyObjectInPrefab(selected.transform);
}
}
if(GUILayout.Button("Get Info"))
{
TransformSaver.SaveTransform(null, Selection.gameObjects[0]);
}
GUI.enabled = false;
EditorGUILayout.LabelField("Selection count: " + Selection.gameObjects.Length);
}
private GameObject[] CheckParents(params GameObject[] objects)
{
List<GameObject> parents = new List<GameObject>(objects.Length);
Transform[] transforms = objects.Select(go => go.transform).ToArray();
for (int objectIndex = 0; objectIndex < transforms.Length; objectIndex++)
{
if (!IsChildOfAny(transforms[objectIndex], transforms))
parents.Add(transforms[objectIndex].gameObject);
}
return parents.ToArray();
}
private bool IsChildOfAny(Transform potentialChild, params Transform[] potentialParents)
{
for (int index = 0; index < potentialParents.Length; index++)
{
if (IsParentOf(potentialParents[index], potentialChild))
return true;
}
return false;
}
private bool IsParentOf(Transform potentialParent, Transform potentialChild)
{
if (potentialChild.parent == null)
return false;
if (potentialChild.parent == potentialParent)
return true;
return IsParentOf(potentialParent, potentialChild.parent);
}
private void DestroyObjectInPrefab(Transform transform)
{
if (PrefabUtility.IsPartOfPrefabInstance(transform))
{
//if a part of a prefab instance then get the instance handle
Object prefabInstance = PrefabUtility.GetPrefabInstanceHandle(transform);
//destroy the handle
if (prefabInstance != null)
{
Undo.DestroyObjectImmediate(prefabInstance);
}
}
//the usual destroy immediate to clean up scene objects
//DestroyImmediate(transform.gameObject, true);
Undo.DestroyObjectImmediate(transform.gameObject);
}
private void OnSelectionChange()
{
Repaint();
}
}
Я выбираю эту дверь, дверь находится внутри космической станции, и дверь является дочерним элементом другого игрового объекта, а другой игровой объект также является дочерним:
Затем у меня есть сборный дом, который я хочу заменить дверью: сборный - это та же дверь, которую я только что изменил, две двери посередине сделал их красным, но сборный - это просто дверь, как на первом скриншоте. Масштабирование одинакового размера:
Затем при замене префаба он находится немного дальше от того места, где находилась дверь, но в инспекторе я вижу то же положение, что и дверь:
Теперь сборный дом расположен намного глубже внутри комнаты. Если я изменю положение и поворот в моем коде на локальные, то сборный объект будет перемещен намного вперед. Он никогда не встанет на место двери.
Я пробовал другие сценарии замены, которые дают одинаковый результат / с. Я ничего не менял в префабе (префаб - это дверь), только добавил эти цвета.