Last active
September 16, 2024 13:51
-
-
Save karljj1/8313a4a6d0fe6688bd5f8b90db3f72c8 to your computer and use it in GitHub Desktop.
Polymorphism using UxmlAttribute
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using UnityEditor; | |
using UnityEditor.UIElements; | |
using UnityEngine; | |
using UnityEngine.UIElements; | |
// Our Interface. | |
public interface IMyInterface | |
{ | |
} | |
// Example implementations of the interface. | |
[Serializable] | |
public class MyInterfaceImplementation : IMyInterface | |
{ | |
public int someValue; | |
} | |
[Serializable] | |
public class MyOtherInterfaceImplementation : IMyInterface | |
{ | |
public string someString; | |
public float someFloat; | |
} | |
// Our class that contains a reference to the interface. | |
[Serializable] | |
public class MyClass | |
{ | |
[SerializeReference] | |
public IMyInterface myInterface; | |
} | |
// The converter class. This converts to and from the string representation of the interface instance | |
public class MyClassConverter : UxmlAttributeConverter<MyClass> | |
{ | |
public override MyClass FromString(string value) | |
{ | |
return JsonUtility.FromJson<MyClass>(value); | |
} | |
public override string ToString(MyClass value) | |
{ | |
return JsonUtility.ToJson(value); | |
} | |
} | |
// The UXML element that uses the MyClass type. | |
[UxmlElement] | |
public partial class MyElement : VisualElement | |
{ | |
[UxmlAttribute] | |
public MyClass myClass { get; set; } | |
} | |
// The property drawer for the MyClass type. So we can give users options on what type to create. | |
[CustomPropertyDrawer(typeof(MyClass))] | |
public class MyDrawer : PropertyDrawer | |
{ | |
public override VisualElement CreatePropertyGUI(SerializedProperty property) | |
{ | |
var p = property.FindPropertyRelative("myInterface"); | |
var root = new VisualElement(); | |
root.Add(new Button(() => | |
{ | |
p.managedReferenceValue = new MyInterfaceImplementation(); | |
property.serializedObject.ApplyModifiedProperties(); | |
}) | |
{ text = "MyterfaceImplementation" }); | |
root.Add(new Button(() => | |
{ | |
p.managedReferenceValue = new MyOtherInterfaceImplementation(); | |
property.serializedObject.ApplyModifiedProperties(); | |
}) | |
{ text = "MyOtherInterfaceImplementation" }); | |
root.Add(new PropertyField(p)); | |
return root; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Example UXML