C# 为什么用预设替换游戏对象时,预设位置有点向后,而不是完全在游戏对象位置上?

C# 为什么用预设替换游戏对象时,预设位置有点向后,而不是完全在游戏对象位置上?,c#,unity3d,C#,Unity3d,这是用于替换的代码: using System.Collections; using System.Collections.Generic; using System.Linq; using UnityEditor; using UnityEngine; public class SaveTransformsInfo : EditorWindow { [SerializeField] private GameObject prefab; [MenuItem("Tools/Re

这是用于替换的代码:

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();
    }
}
使用系统集合;
使用System.Collections.Generic;
使用System.Linq;
使用UnityEditor;
使用UnityEngine;
公共类SaveTransformsInfo:EditorWindow
{
[SerializeField]私有游戏对象预制;
[菜单项(“工具/替换为预制件”)]
静态void CreateReplaceWithPrefact()
{
EditorWindow.GetWindow();
}
私有void OnGUI()
{
预置=(游戏对象)EditorGUILayout.ObjectField(“预置”,预置,typeof(游戏对象),false);
if(预置==null | | Selection.gameObjects.Length==0)
{
GUI.enabled=false;
}
其他的
{
GUI.enabled=true;
}
如果(GUILayout.按钮(“替换”))
{
var selection=selection.gameObjects;
var parentGameobjects=CheckParents(选择);
#如果统一编辑器
UnityEditor.Selection.objects=父游戏对象;
#恩迪夫
对于(var i=parentGameobjects.Length-1;i>=0;--i)
{
var selected=parentGameobjects[i];
var prefableType=prefableUtility.getPrefableType(prefable);
游戏对象新对象;
if(prefableType==prefableType.prefable)
{
newObject=(游戏对象)预置实用程序。实例化预置(预置);
}
其他的
{
newObject=实例化(预置);
newObject.name=prefact.name;
}
if(newObject==null)
{
LogError(“实例化预置时出错”);
打破
}
RegisterCreatedObjectUndo(newObject,“替换为预置”);
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(选定的.transform);
}
}
if(GUILayout.Button(“获取信息”))
{
SaveTransform(null,Selection.gameObjects[0]);
}
GUI.enabled=false;
LabelField(“选择计数:”+Selection.gameObjects.Length);
}
私有GameObject[]检查父对象(参数GameObject[]对象)
{
列表父项=新列表(objects.Length);
Transform[]transforms=objects.Select(go=>go.Transform.ToArray();
for(int objectIndex=0;objectIndex
我选择了这扇门,这扇门在空间站里面,这扇门是另一个游戏对象的子对象,另一个游戏对象也是子对象:

然后我有一个预制件,我想用门替换它: 预制件是同一扇门,我只是改变了中间的两扇门,使它们变成红色,但是预制件只是第一幕截图中的一扇门。相同大小的缩放:

然后,在进行更换时,预制件的位置与门的位置有点背,但在检查员处,我看到的位置与门的位置相同:

现在预制件被放置在房间的后面。 如果我将代码中的位置和旋转更改为local,那么预制件的位置将向前移动很多。它永远不会位于门的位置

我尝试了其他替换脚本,它们都给出了相同的结果。
我没有在预制件(预制件是门)中更改任何内容,只添加了此颜色。

这是因为预制件的中心与原始对象的中心不同

可以通过将对象放在空对象中并将其移动到该对象的局部位置来重新居中该对象

然后可以将该对象用作场景中的预设


如果你只是想换颜色,那么希望它能帮上忙

GameObject.GetComponent().material=material;