Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

How can I do a copy/paste on SerializedProperty?

Discussion in 'Scripting' started by jayatubi, Jul 18, 2019.

  1. jayatubi

    jayatubi

    Joined:
    Dec 9, 2013
    Posts:
    143
    I have a custom serializable class as a field of my component and I created a property drawer for it like:

    Code (csharp):
    1.  
    2. [Serializable]
    3. public class MyInnerClass
    4. {
    5.     public int value;
    6. }
    7. [Serializable]
    8. public class MyClass
    9. {
    10.     public int value;
    11.     public MyInnerClass innerValue;
    12. }
    13. public class MyComponent : MonoBehaviour
    14. {
    15.     [SerializedField]
    16.     public MyClass data;
    17. }
    18.  
    19. [CustomPropertyDrawer(typeof(MyClass))]
    20. public class MyClassDrawer : PropertyDrawer
    21. {
    22. }
    23.  
    And when I add more than one MyComponent into the scene I want add a context menu to the MyClassDrawer which could do a copy/paste function so I can copy the values on one MyClass to another.

    And here are my questions:

    1. In the MyClassDrawer I can only handle the SerializedProperty but the SerializedProperty doesn't provide an interface to CopyFrom others.
    2. MyClass is not inherited from UnityEngine.Object thus the EditorUtility.CopySerialized can't work here.
    3. I'm looking for a generic solution to copy to/from between SerializedProperty without get into the details of each class to copy the fields one by one.
     
    c8theino, SolidAlloy and Furgon13 like this.
  2. Furgon13

    Furgon13

    Joined:
    Jun 5, 2018
    Posts:
    2
    Hello! Are you found answer to your question?
     
  3. c8theino

    c8theino

    Joined:
    Jun 1, 2019
    Posts:
    20
    I would also like to know how to do this...
     
  4. julienkay

    julienkay

    Joined:
    Nov 12, 2013
    Posts:
    167
    It seems when implementing the custom PropertyDrawer by overriding OnGUI() using EditorGUI.BeginProperty / EditorGUI.EndProperty() you get prefab override logic and the right click copy context menu for free.
    (I found out just by using the example code from the PropertyDrawer documentation page).

    This is the code I tested this with:
    Code (CSharp):
    1. using System;
    2. using UnityEditor;
    3. using UnityEngine;
    4.  
    5. public class MyComponent : MonoBehaviour {
    6.     [SerializeField]
    7.     public MyClass data;
    8. }
    9. [Serializable]
    10. public class MyInnerClass {
    11.     public int value;
    12. }
    13. [Serializable]
    14. public class MyClass {
    15.     public int value;
    16.     public MyInnerClass innerValue;
    17. }
    18.  
    19. [CustomPropertyDrawer(typeof(MyClass))]
    20. public class MyClassDrawer : PropertyDrawer {
    21.  
    22.     public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) {
    23.         // Using BeginProperty / EndProperty on the parent property means that
    24.         // prefab override logic works on the entire property.
    25.         EditorGUI.BeginProperty(position, label, property);
    26.  
    27.         // Draw label
    28.         position = EditorGUI.PrefixLabel(position, GUIUtility.GetControlID(FocusType.Passive), label);
    29.  
    30.         // Calculate rects
    31.         var value = new Rect(position.x, position.y, 30, position.height);
    32.         var innerValue = new Rect(position.x + 35, position.y, 50, position.height);
    33.  
    34.         // Draw fields - passs GUIContent.none to each so they are drawn without labels
    35.         EditorGUI.PropertyField(value, property.FindPropertyRelative("value"), GUIContent.none);
    36.         EditorGUI.PropertyField(innerValue, property.FindPropertyRelative("innerValue.value"), GUIContent.none);
    37.  
    38.  
    39.         EditorGUI.EndProperty();
    40.     }
    41. }
    42.  

    And this is the result:
    Recording 2022-04-06 at 21.37.11.gif https://docs.unity3d.com/ScriptReference/EditorGUI.BeginProperty.html
     
    forestrf, Gamba04 and mgear like this.
  5. lgarczyn

    lgarczyn

    Joined:
    Nov 23, 2014
    Posts:
    68
    Lovely! Thanks so much
     
  6. Ruchir

    Ruchir

    Joined:
    May 26, 2015
    Posts:
    934
    How can we do something similar for UI elements?
     
  7. lgarczyn

    lgarczyn

    Joined:
    Nov 23, 2014
    Posts:
    68
    PropertyElement should support this by default
     
  8. Ruchir

    Ruchir

    Joined:
    May 26, 2015
    Posts:
    934
    Yeah, but I want to create custom property drawers, so, right now they don't support it, if add a custom label they don't work as they did when using IMGUI.
     
  9. lgarczyn

    lgarczyn

    Joined:
    Nov 23, 2014
    Posts:
    68
    UIElements are great when dealing with "meta" stuff, but if you're doing a single element that can be used in both IMGUI and UIElement contexts, it's still better to use IMGUI