using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEditor;
using UnityEngine;
using UnityEngine.SceneManagement;
public class PrefabReplace : EditorWindow
{
[SerializeField] private GameObject prefab;
GameObject newobj;
[MenuItem("Tools/Prefab Replace")]
static void CreateReplaceWithPrefab()
{
EditorWindow.GetWindow<PrefabReplace>();
}
private void OnGUI()
{
prefab = (GameObject)EditorGUILayout.ObjectField("Prefab", prefab, typeof(GameObject), false);
if (GUILayout.Button("Replace"))
{
var selection = Selection.gameObjects.ToList();
if (prefab != null && selection.Count > 0)
{
for (var i = selection.Count - 1; i >= 0; --i)
{
var selected = selection[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.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);
}
}
}
if (GUILayout.Button("Write settings"))
{
var selection = Selection.gameObjects.ToList();
if (selection.Count > 0)
{
for (int i = selection.Count - 1; i >= 0; --i)
{
var selected = selection[i].transform;
string toWrite = $"{selected.parent}:{selected.localPosition}:{selected.localRotation}:{selected.localScale}";
WriteDataToFile(toWrite);
}
}
}
if (GUILayout.Button("Read settings"))
{
var obj = GetObjectFromFile("Assets/Resources/test.txt");
Instantiate(obj);
DestroyImmediate(newobj);
}
GUI.enabled = false;
EditorGUILayout.LabelField("Selection count: " + Selection.objects.Length);
}
private void OnInspectorUpdate()
{
Repaint();
}
private void WriteDataToFile(string line)
{
string path = "Assets/Resources/test.txt";
StreamWriter writer = new StreamWriter(path, true);
writer.WriteLine(line);
writer.Close();
}
private GameObject GetObjectFromFile(string path)
{
newobj = new GameObject();
string[] text = new string[3];
if (File.Exists(path))
{
text = File.ReadAllLines(path);
foreach (string s in text)
{
text = s.Split(':');
break;
}
var parent = text[0].Substring(0, text[0].IndexOf(" ("));
var localPosition = StringToVector3(text[1]);
var localRotation = StringToQuaternion(text[2]);
var localScale = StringToVector3(text[3]);
if (parent != null)
{
GameObject toparent = GameObject.Find(parent);
newobj.transform.parent = toparent.transform;
}
newobj.transform.localPosition = localPosition;
newobj.transform.localRotation = localRotation;
newobj.transform.localScale = localScale;
}
return newobj;
}
public static Vector3 StringToVector3(string sVector)
{
// Remove the parentheses
if (sVector.StartsWith("(") && sVector.EndsWith(")"))
{
sVector = sVector.Substring(1, sVector.Length - 2);
}
// split the items
string[] sArray = sVector.Split(',');
// store as a Vector3
Vector3 result = new Vector3(
float.Parse(sArray[0]),
float.Parse(sArray[1]),
float.Parse(sArray[2]));
return result;
}
public static Quaternion StringToQuaternion(string sQuaternion)
{
// Remove the parentheses
if (sQuaternion.StartsWith("(") && sQuaternion.EndsWith(")"))
{
sQuaternion = sQuaternion.Substring(1, sQuaternion.Length - 2);
}
// split the items
string[] sArray = sQuaternion.Split(',');
// store as a Vector3
Quaternion result = new Quaternion(
float.Parse(sArray[0]),
float.Parse(sArray[1]),
float.Parse(sArray[2]),
float.Parse(sArray[3]));
return result;
}
}
当我在线路上放置一个断点时:
DestroyImmediate(newobj);
我看到变量obj很好并且不为null。 但是,当我单击继续时,我看到变量obj为空。 我要销毁newobj,然后为什么它不记得obj中的值?我不想为obj创建新实例,因为它将为层次结构添加新的GameObject。我只想将值分配给新的游戏对象。
答案 0 :(得分:3)
如果要分配具有相同数据的新对象,请使用以下结构:
var newobj = new Type(oldObj);
这样会复制内容,并留下2个单独的对象。
例如var obj = new ObjectClass(GetObjectFromFile("Assets/Resources/test.txt"));