From 6b1a3a6a8691361989b5048e7527ae3e80bfe70e Mon Sep 17 00:00:00 2001 From: Vladislav Date: Sun, 7 Jul 2024 22:57:16 +0300 Subject: [PATCH] Add: Serialize Reference copy and paste item data support ManagedReferenceContextMenuExtension handles that --- .../ManagedReferenceContextMenuExtension.cs | 57 +++++++++++++++++++ ...nagedReferenceContextMenuExtension.cs.meta | 11 ++++ 2 files changed, 68 insertions(+) create mode 100644 Alchemy/Assets/Alchemy/Editor/Internal/ManagedReferenceContextMenuExtension.cs create mode 100644 Alchemy/Assets/Alchemy/Editor/Internal/ManagedReferenceContextMenuExtension.cs.meta diff --git a/Alchemy/Assets/Alchemy/Editor/Internal/ManagedReferenceContextMenuExtension.cs b/Alchemy/Assets/Alchemy/Editor/Internal/ManagedReferenceContextMenuExtension.cs new file mode 100644 index 0000000..d75f3c0 --- /dev/null +++ b/Alchemy/Assets/Alchemy/Editor/Internal/ManagedReferenceContextMenuExtension.cs @@ -0,0 +1,57 @@ +#if UNITY_2021_3_OR_NEWER +using UnityEditor; +using UnityEngine; + +namespace Alchemy.Editor { + public static class ManagedReferenceContextMenuExtension { + + private const string CLIPBOARD_KEY = "AlchemyExtensions.CopyAndPasteManagedProperty"; + private const string COPIED_PROPERTY_PATH_KEY = "AlchemyExtensions.CopiedManagedPropertyPath"; + + private static readonly GUIContent CopyProperty = new("Copy Property"); + private static readonly GUIContent PasteProperty = new("Paste Property"); + + [InitializeOnLoadMethod] + private static void Initialize() { + EditorApplication.contextualPropertyMenu += OnContextualPropertyMenu; + } + + private static void OnContextualPropertyMenu(GenericMenu menu, SerializedProperty property) { + if (property.propertyType == SerializedPropertyType.ManagedReference) { + + SerializedProperty clonedProperty = property.Copy(); + menu.AddItem(CopyProperty, false, Copy, clonedProperty); + + string copiedPropertyPath = SessionState.GetString(COPIED_PROPERTY_PATH_KEY, string.Empty); + if (!string.IsNullOrEmpty(copiedPropertyPath)) { + menu.AddItem(PasteProperty, false, Paste, clonedProperty); + } + else { + menu.AddDisabledItem(PasteProperty); + } + + menu.AddSeparator(""); + } + } + + private static void Copy(object serializedPropertyObject) { + SerializedProperty property = (SerializedProperty)serializedPropertyObject; + string json = JsonUtility.ToJson(property.managedReferenceValue); + SessionState.SetString(COPIED_PROPERTY_PATH_KEY, property.propertyPath); + SessionState.SetString(CLIPBOARD_KEY, json); + } + + private static void Paste(object serializedPropertyObject) { + SerializedProperty property = (SerializedProperty)serializedPropertyObject; + string json = SessionState.GetString(CLIPBOARD_KEY, string.Empty); + if (string.IsNullOrEmpty(json)) { + return; + } + + Undo.RecordObject(property.serializedObject.targetObject, PasteProperty.text); + JsonUtility.FromJsonOverwrite(json, property.managedReferenceValue); + property.serializedObject.ApplyModifiedProperties(); + } + } +} +#endif \ No newline at end of file diff --git a/Alchemy/Assets/Alchemy/Editor/Internal/ManagedReferenceContextMenuExtension.cs.meta b/Alchemy/Assets/Alchemy/Editor/Internal/ManagedReferenceContextMenuExtension.cs.meta new file mode 100644 index 0000000..a3ab742 --- /dev/null +++ b/Alchemy/Assets/Alchemy/Editor/Internal/ManagedReferenceContextMenuExtension.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7f3d08b9bd5850442a8eacb8b1cb7f05 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: