Skip to content

Instantly share code, notes, and snippets.

@synasius
Last active April 10, 2023 20:07
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save synasius/618d3498d34956df85b141565640c00e to your computer and use it in GitHub Desktop.
Save synasius/618d3498d34956df85b141565640c00e to your computer and use it in GitHub Desktop.
UI Toolkit Serializable Id
using System;
using UnityEngine;
/// <summary>
/// A generic serializable GUID.
/// </summary>
[Serializable]
public struct SerializableId<T> : IComparable<SerializableId<T>>, IEquatable<SerializableId<T>>, ISerializationCallbackReceiver
{
[SerializeField] private string _guid;
public Guid Value { get; private set; }
public SerializableId(Guid newGuid)
{
Value = newGuid;
_guid = Value.ToString();
}
public static SerializableId<T> New() => new SerializableId<T>(Guid.NewGuid());
public void OnBeforeSerialize()
{
_guid = Value.ToString();
}
public void OnAfterDeserialize()
{
if (Guid.TryParse(_guid, out var value))
Value = value;
else
Value = Guid.Empty;
}
public int CompareTo(SerializableId<T> other) => Value.CompareTo(other);
public bool Equals(SerializableId<T> other) => Value.Equals(other.Value);
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
return obj is SerializableId<T> other && Equals(other);
}
public override int GetHashCode() => Value.GetHashCode();
public override string ToString() => Value.ToString();
public static bool operator ==(SerializableId<T> a, SerializableId<T> b) => a.CompareTo(b) == 0;
public static bool operator !=(SerializableId<T> a, SerializableId<T> b) => !(a == b);
}
using System;
using UnityEditor;
using UnityEditor.UIElements;
using UnityEngine.UIElements;
[CustomPropertyDrawer(typeof(SerializableId<>))]
public class SerializableIdPropertyDrawer : PropertyDrawer
{
public override VisualElement CreatePropertyGUI(SerializedProperty property)
{
var container = new VisualElement();
var guidProperty = property.FindPropertyRelative("_guid");
var guidField = new PropertyField(guidProperty);
guidField.SetEnabled(false);
container.Add(guidField);
var generateButton = new Button();
generateButton.text = "Generate";
generateButton.clicked += () =>
{
var guid = Guid.NewGuid().ToString();
guidProperty.stringValue = guid;
guidProperty.serializedObject.ApplyModifiedProperties();
};
container.Add(generateButton);
return container;
}
}
[Serializable]
public class Item
{
[SerializeField] private SerializableId<Item> _id;
}
public class ItemList : ScriptableObject
{
[SerializeField] private List<Item> _items;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment