188 lines
6.2 KiB
C#
188 lines
6.2 KiB
C#
/*
|
|
A simple little editor extension to copy and paste all components
|
|
Help from http://answers.unity3d.com/questions/541045/copy-all-components-from-one-character-to-another.html
|
|
license: WTFPL (http://www.wtfpl.net/)
|
|
author: aeroson
|
|
advise: ChessMax
|
|
editor: frekons
|
|
*/
|
|
|
|
#if UNITY_EDITOR
|
|
using UnityEngine;
|
|
using UnityEditor;
|
|
using System.Collections.Generic;
|
|
|
|
public class CopyMultipleComponents : EditorWindow
|
|
{
|
|
// Use ScriptableObject to store data between editor sessions
|
|
private class ComponentDataContainer : ScriptableObject
|
|
{
|
|
public List<string> componentData = new List<string>();
|
|
public List<string> componentTypeNames = new List<string>();
|
|
}
|
|
|
|
private static ComponentDataContainer dataContainer;
|
|
|
|
[MenuItem("Tools/Component Utilities/Copy All Components")]
|
|
static void Copy()
|
|
{
|
|
if (Selection.activeGameObject == null)
|
|
{
|
|
Debug.LogError("No GameObject selected for copying!");
|
|
return;
|
|
}
|
|
|
|
// Create or get the data container
|
|
if (dataContainer == null)
|
|
dataContainer = ScriptableObject.CreateInstance<ComponentDataContainer>();
|
|
|
|
dataContainer.componentData.Clear();
|
|
dataContainer.componentTypeNames.Clear();
|
|
|
|
Component[] components = Selection.activeGameObject.GetComponents<Component>();
|
|
|
|
foreach (Component component in components)
|
|
{
|
|
if (component == null)
|
|
continue;
|
|
|
|
// Skip Transform component as it often causes issues
|
|
if (component is Transform)
|
|
continue;
|
|
|
|
// Store component data as JSON
|
|
string json = EditorJsonUtility.ToJson(component);
|
|
dataContainer.componentData.Add(json);
|
|
dataContainer.componentTypeNames.Add(component.GetType().AssemblyQualifiedName);
|
|
}
|
|
|
|
if (dataContainer.componentData.Count > 0)
|
|
{
|
|
Debug.Log($"Copied {dataContainer.componentData.Count} components from {Selection.activeGameObject.name}");
|
|
}
|
|
else
|
|
{
|
|
Debug.LogWarning("No components found to copy!");
|
|
}
|
|
}
|
|
|
|
[MenuItem("Tools/Component Utilities/Paste All Components")]
|
|
static void Paste()
|
|
{
|
|
if (dataContainer == null || dataContainer.componentData.Count == 0)
|
|
{
|
|
Debug.LogError("Nothing is copied! Use 'Copy All Components' first.");
|
|
return;
|
|
}
|
|
|
|
foreach (GameObject targetGameObject in Selection.gameObjects)
|
|
{
|
|
if (!targetGameObject)
|
|
continue;
|
|
|
|
Undo.RegisterCompleteObjectUndo(targetGameObject, targetGameObject.name + ": Paste All Components");
|
|
|
|
int successCount = 0;
|
|
int failCount = 0;
|
|
|
|
for (int i = 0; i < dataContainer.componentTypeNames.Count; i++)
|
|
{
|
|
string typeString = dataContainer.componentTypeNames[i];
|
|
string jsonData = dataContainer.componentData[i];
|
|
|
|
System.Type componentType = System.Type.GetType(typeString);
|
|
if (componentType == null)
|
|
{
|
|
Debug.LogError($"Could not find type: {typeString}");
|
|
failCount++;
|
|
continue;
|
|
}
|
|
|
|
// Check if component already exists
|
|
Component targetComponent = targetGameObject.GetComponent(componentType);
|
|
|
|
if (targetComponent == null)
|
|
{
|
|
// Add component if it doesn't exist
|
|
targetComponent = Undo.AddComponent(targetGameObject, componentType);
|
|
}
|
|
|
|
if (targetComponent != null)
|
|
{
|
|
// Apply the JSON data to the component
|
|
EditorJsonUtility.FromJsonOverwrite(jsonData, targetComponent);
|
|
successCount++;
|
|
}
|
|
else
|
|
{
|
|
Debug.LogError($"Failed to add component: {componentType}");
|
|
failCount++;
|
|
}
|
|
}
|
|
|
|
Debug.Log($"Pasted to {targetGameObject.name}: {successCount} components successful, {failCount} failed");
|
|
}
|
|
}
|
|
|
|
[MenuItem("Tools/Component Utilities/Delete All Components")]
|
|
static void DeleteAllComponents()
|
|
{
|
|
if (Selection.gameObjects.Length == 0)
|
|
{
|
|
Debug.LogError("No GameObjects selected for component deletion!");
|
|
return;
|
|
}
|
|
|
|
foreach (GameObject targetGameObject in Selection.gameObjects)
|
|
{
|
|
if (!targetGameObject)
|
|
continue;
|
|
|
|
Undo.RegisterCompleteObjectUndo(targetGameObject, targetGameObject.name + ": Delete All Components");
|
|
|
|
Component[] components = targetGameObject.GetComponents<Component>();
|
|
int deletedCount = 0;
|
|
|
|
// Start from the end to avoid index issues when destroying components
|
|
for (int i = components.Length - 1; i >= 0; i--)
|
|
{
|
|
Component component = components[i];
|
|
|
|
// Skip null components
|
|
if (component == null)
|
|
continue;
|
|
|
|
// Skip Transform component as it's required
|
|
if (component is Transform)
|
|
continue;
|
|
|
|
// Destroy the component with Undo support
|
|
Undo.DestroyObjectImmediate(component);
|
|
deletedCount++;
|
|
}
|
|
|
|
Debug.Log($"Deleted {deletedCount} components from {targetGameObject.name}");
|
|
}
|
|
}
|
|
|
|
// Add menu items without keyboard shortcuts
|
|
[MenuItem("GameObject/Component Utilities/Copy All Components")]
|
|
static void CopyFromGameObjectMenu()
|
|
{
|
|
Copy();
|
|
}
|
|
|
|
[MenuItem("GameObject/Component Utilities/Paste All Components")]
|
|
static void PasteFromGameObjectMenu()
|
|
{
|
|
Paste();
|
|
}
|
|
|
|
[MenuItem("GameObject/Component Utilities/Delete All Components")]
|
|
static void DeleteAllComponentsFromGameObjectMenu()
|
|
{
|
|
DeleteAllComponents();
|
|
}
|
|
}
|
|
#endif
|