使用场景
在建好场景白盒后,想将美术资源替换进去,但多个美术资源重复,所以自己研究了一下如何使用编辑器脚本达到目的。
代码:
选中一个或多个物体后,将要替换成的目标物体拖入窗口即可。不过当前使用该代码替换后会产生轻微位移。同时撤回功能有问题,正在修复。
using UnityEngine;
using UnityEditor;
public class ReplaceObjectTool : EditorWindow
{
private Object objectB;
private GameObject[] selectedObjects;
private GameObject[] copiedObjectsB;
[MenuItem("Tools/Replace Object Tool")]
private static void ShowWindow()
{
ReplaceObjectTool window = GetWindow<ReplaceObjectTool>();
window.titleContent = new GUIContent("Replace Object Tool");
window.Show();
}
private void OnGUI()
{
GUILayout.Label("Drag Object B from another scene here:", EditorStyles.boldLabel);
objectB = EditorGUILayout.ObjectField(objectB, typeof(Object), true);
if (GUILayout.Button("Replace Selected Objects"))
{
ReplaceObjects();
}
if (GUILayout.Button("Undo"))
{
UndoReplace();
}
if (GUILayout.Button("Redo"))
{
RedoReplace();
}
}
private void ReplaceObjects()
{
if (Selection.gameObjects == null || Selection.gameObjects.Length == 0 || objectB == null)
{
Debug.LogWarning("No objects selected or Object B is not assigned!");
return;
}
selectedObjects = Selection.gameObjects;
// Record the current state for Undo
Undo.RecordObjects(selectedObjects, "Replace Objects");
// Replace selected objects with object B
foreach (var obj in selectedObjects)
{
GameObject newObject = null;
if (PrefabUtility.IsPartOfPrefabAsset(objectB))
{
newObject = (GameObject)PrefabUtility.InstantiatePrefab(objectB);
newObject.transform.position = obj.transform.position;
newObject.transform.rotation = obj.transform.rotation;
newObject.transform.localScale = obj.transform.localScale;
}
else if (objectB is GameObject)
{
newObject = Instantiate((GameObject)objectB, obj.transform.position, obj.transform.rotation);
newObject.transform.localScale = obj.transform.localScale;
}
else
{
Debug.LogWarning("Invalid object type for replacement!");
return;
}
if (newObject != null)
{
newObject.transform.parent = obj.transform.parent;
newObject.transform.SetSiblingIndex(obj.transform.GetSiblingIndex());
Undo.RegisterCreatedObjectUndo(newObject, "Replace Objects");
DestroyImmediate(obj);
}
}
}
private void UndoReplace()
{
// Undo the replace operation
if (selectedObjects != null)
{
foreach (var obj in selectedObjects)
{
GameObject newObject = null;
if (PrefabUtility.IsPartOfPrefabInstance(obj))
{
newObject = (GameObject)PrefabUtility.GetCorrespondingObjectFromSource(obj);
newObject = PrefabUtility.InstantiatePrefab(newObject) as GameObject;
newObject.transform.position = obj.transform.position;
newObject.transform.rotation = obj.transform.rotation;
newObject.transform.localScale = obj.transform.localScale;
}
else
{
newObject = Instantiate(obj, obj.transform.position, obj.transform.rotation);
newObject.transform.localScale = obj.transform.localScale;
}
if (newObject != null)
{
newObject.transform.parent = obj.transform.parent;
newObject.transform.SetSiblingIndex(obj.transform.GetSiblingIndex());
Undo.RegisterCreatedObjectUndo(newObject, "Undo Replace Objects");
DestroyImmediate(obj);
}
}
}
}
private void RedoReplace()
{
// Redo the replace operation
ReplaceObjects();
}
}
使用方法:
在Tools中选择该工具,弹出新窗口的两个按钮,可以一键开启选中物体的Emission或关闭。注:该工具只管理拥有MeshFilter组件的物体,对于使用SkinnMeshFilter的带蒙皮人物无法使用。