Unity 一鍵替換場景中的物體

實現場景中批量替換預製體的編輯器功能。

一、關鍵api

PrefabUtility.InstantiatePrefab 將預設實例化到場景中,與GameObject.Instantiate不同,它是以預設實例的。

二、工具截圖

三、使用方法

在Project中拖拽預設到工具中

打開需要操作的場景,可以多選需要替換的物體,或者輸入需要替換的名字

修改完成後保存場景

四、代碼

using System.Collections.Generic;
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine;

public class ObjectReplaceEditorWindow : EditorWindow
{
    [MenuItem("Tools/替換場景中的物體")]
    public static void Open()
    {
        EditorWindow.GetWindow(typeof(ObjectReplaceEditorWindow));
    }
    public GameObject newPrefab;
    static GameObject tonewPrefab;
    private string replaceName = "";
    private bool isChangeName = false;
    public class ReplaceData
    {
        public GameObject old;
        public GameObject replace;
        public int index = 0;
    }
    void OnGUI()
    {
        EditorGUILayout.LabelField("選擇一個新的物體");
        newPrefab = (GameObject) EditorGUILayout.ObjectField(newPrefab, typeof(GameObject),true, GUILayout.MinWidth(100f));
        tonewPrefab = newPrefab;
        //isChangeName = EditorGUILayout.ToggleLeft("不改變場景中物體的名字", isChangeName);
        if (GUILayout.Button("替換選中的物體"))
        {
            ReplaceObjects();
        }
        EditorGUILayout.LabelField("----------------------");
        replaceName = EditorGUILayout.TextField("需要替換的物體名字", replaceName);
        if (GUILayout.Button("替換相同名字的"))
        {
            ReplaceObjectsByName(replaceName, false);
        }
        if (GUILayout.Button("替換包含名字的 慎用"))
        {
            ReplaceObjectsByName(replaceName, true);
        }
        EditorGUILayout.LabelField("----------------------");
        if (GUILayout.Button("保存修改"))
        {
            EditorSceneManager.SaveScene(UnityEngine.SceneManagement.SceneManager.GetActiveScene());
        }
    }
    void ReplaceObjects()
    {
        if (tonewPrefab == null) return;
        Object[] objects = Selection.objects;
        List<ReplaceData> replaceDatas = new List<ReplaceData>();
        foreach (Object item in objects)
        {
            GameObject temp = (GameObject)item;
            ReplaceData replaceData = new ReplaceData();
            replaceData.old = temp;
            ReplaceOne(replaceData);
            replaceDatas.Add(replaceData);
        }
        HandleReplaceData(replaceDatas);
    }
    void HandleReplaceData(List<ReplaceData> replaceDatas)
    {
        foreach (var replaceData in replaceDatas)
        {
            replaceData.replace.transform.SetSiblingIndex(replaceData.index);
            if(null != replaceData.old && null != replaceData.old.gameObject)
                DestroyImmediate(replaceData.old.gameObject);
        }
    }
    void ReplaceObjectsByName(string name, bool isContain)
    {
        if (string.IsNullOrEmpty(name)) return;
        List<ReplaceData> replaceDatas = new List<ReplaceData>();
        Transform[] all = Object.FindObjectsOfType<Transform>();
        foreach (var item in all)
        {
            //Debug.LogError(item.name);
            ReplaceData replaceData = new ReplaceData();
            replaceData.old = item.gameObject;
            if (!isContain && item.gameObject.name == name)
            {
                ReplaceOne(replaceData);
                replaceDatas.Add(replaceData);
            }
            else if (isContain && item.gameObject.name.Contains(name))
            {
                ReplaceOne(replaceData);
                replaceDatas.Add(replaceData);
            }
        }
        HandleReplaceData(replaceDatas);
    }
 
    public void ReplaceOne(ReplaceData replaceData)
    {
        GameObject replace = (GameObject)PrefabUtility.InstantiatePrefab(tonewPrefab);
        replace.transform.SetParent(replaceData.old.transform.parent);
        replace.transform.localPosition = replaceData.old.transform.localPosition;
        replace.transform.localRotation = replaceData.old.transform.localRotation;
        replace.transform.localScale = replaceData.old.transform.localScale;
        replaceData.replace = replace;
        replaceData.index = replaceData.old.transform.GetSiblingIndex();
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章