Это код для замены:
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();
}
}
Я выбираю эту дверь, дверь находится внутри космической станции, и дверь является дочерней для другого игрового объекта, а другой игровой объект также является дочерним:
![Door to replace](https://i.stack.imgur.com/C3JRl.jpg)
Тогда у меня есть сборный домик, я хочу заменить его дверью: сборный домик - это та же дверь, я только что поменял две двери в середине, сделалони в красном, но сборный - просто дверь, как на первом скриншоте. Масштабирование того же размера:
![Prefab to place instead the door](https://i.stack.imgur.com/7zWfL.jpg)
Затем при замене сборного элемента находится немного назад от того места, где была дверь, но в инспекторе я вижута же позиция, что и у двери:
![Replaced prefab](https://i.stack.imgur.com/Hemrd.jpg)
Теперь сборный дом расположен далеко сзади в комнате. Если я изменю положение и поворот в моем коде на локальный, то префаб будет располагаться намного вперед. Он никогда не будет располагаться на месте двери.
Я пробовал другие сценарии замены, все они дают одинаковые результаты. Я ничего не менял в сборном (сборный - это дверь), только добавляю эти цвета.