Files
DeviantMobile-Rohan/Assets/Scripts/Utilities/CopyMultipleComponents.cs

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