// Serialization // Copyright 2020 Kybernetik // #if UNITY_EDITOR using System; using UnityEditor; using UnityEngine; using Object = UnityEngine.Object; // Shared File Last Modified: 2019-12-06. namespace Animancer.Editor // namespace InspectorGadgets.Editor { /// <summary>[Editor-Only] Various serialization utilities.</summary> public partial class Serialization { /// <summary>[Editor-Only] /// Directly serializing an <see cref="UnityEngine.Object"/> reference doesn't always work (such as with scene /// objects when entering Play Mode), so this class also serialized their instance ID and uses that if the direct /// reference fails. /// </summary> [Serializable] public sealed class ObjectReference { /************************************************************************************************************************/ [SerializeField] private Object _Object; [SerializeField] private int _InstanceID; /************************************************************************************************************************/ /// <summary>The referenced <see cref="SerializedObject"/>.</summary> public Object Object { get { Initialise(); return _Object; } } /// <summary>The <see cref="Object.GetInstanceID"/>.</summary> public int InstanceID { get { return _InstanceID; } } /************************************************************************************************************************/ /// <summary> /// Constructs a new <see cref="ObjectReference"/> which wraps the specified /// <see cref="UnityEngine.Object"/>. /// </summary> public ObjectReference(Object obj) { _Object = obj; if (obj != null) _InstanceID = obj.GetInstanceID(); } /************************************************************************************************************************/ private void Initialise() { if (_Object == null) _Object = EditorUtility.InstanceIDToObject(_InstanceID); else _InstanceID = _Object.GetInstanceID(); } /************************************************************************************************************************/ /// <summary> /// Constructs a new <see cref="ObjectReference"/> which wraps the specified /// <see cref="UnityEngine.Object"/>. /// </summary> public static implicit operator ObjectReference(Object obj) { return new ObjectReference(obj); } /// <summary> /// Returns the target <see cref="Object"/>. /// </summary> public static implicit operator Object(ObjectReference reference) { return reference.Object; } /************************************************************************************************************************/ /// <summary> /// Creates a new array of <see cref="ObjectReference"/>s representing the `objects`. /// </summary> public static ObjectReference[] Convert(params Object[] objects) { var references = new ObjectReference[objects.Length]; for (int i = 0; i < objects.Length; i++) references[i] = objects[i]; return references; } /// <summary> /// Creates a new array of <see cref="UnityEngine.Object"/>s containing the target <see cref="Object"/> of each /// of the `references`. /// </summary> public static Object[] Convert(params ObjectReference[] references) { var objects = new Object[references.Length]; for (int i = 0; i < references.Length; i++) objects[i] = references[i]; return objects; } /************************************************************************************************************************/ /// <summary> /// Indicates whether both arrays refer to the same set of objects. /// </summary> public static bool AreSameObjects(ObjectReference[] references, Object[] objects) { if (references == null) return objects == null; if (objects == null) return false; if (references.Length != objects.Length) return false; for (int i = 0; i < references.Length; i++) { if (references[i] != objects[i]) return false; } return true; } /************************************************************************************************************************/ /// <summary>Returns a string describing this object.</summary> public override string ToString() { return "Serialization.ObjectReference [" + _InstanceID + "] " + _Object; } /************************************************************************************************************************/ } /************************************************************************************************************************/ /// <summary>Returns true if the `reference` and <see cref="ObjectReference.Object"/> are not null.</summary> public static bool IsValid(this ObjectReference reference) { return reference != null && reference.Object != null; } /************************************************************************************************************************/ } } #endif