Serialization.ObjectReference.cs 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. // Serialization // Copyright 2018-2024 Kybernetik //
  2. #if UNITY_EDITOR
  3. using System;
  4. using UnityEditor;
  5. using UnityEngine;
  6. using Object = UnityEngine.Object;
  7. // Shared File Last Modified: 2023-08-12.
  8. namespace Animancer.Editor
  9. // namespace InspectorGadgets.Editor
  10. {
  11. /// <summary>[Editor-Only] Various serialization utilities.</summary>
  12. public partial class Serialization
  13. {
  14. /// <summary>[Editor-Only]
  15. /// Directly serializing an <see cref="UnityEngine.Object"/> reference doesn't always work (such as with scene
  16. /// objects when entering Play Mode), so this class also serializes their instance ID and uses that if the
  17. /// direct reference fails.
  18. /// </summary>
  19. [Serializable]
  20. public class ObjectReference
  21. {
  22. /************************************************************************************************************************/
  23. [SerializeField] private Object _Object;
  24. [SerializeField] private int _InstanceID;
  25. /************************************************************************************************************************/
  26. /// <summary>The referenced <see cref="SerializedObject"/>.</summary>
  27. public Object Object
  28. {
  29. get
  30. {
  31. Initialize();
  32. return _Object;
  33. }
  34. }
  35. /// <summary>The <see cref="Object.GetInstanceID"/>.</summary>
  36. public int InstanceID => _InstanceID;
  37. /************************************************************************************************************************/
  38. /// <summary>
  39. /// Creates a new <see cref="ObjectReference"/> which wraps the specified
  40. /// <see cref="UnityEngine.Object"/>.
  41. /// </summary>
  42. public ObjectReference(Object obj)
  43. {
  44. _Object = obj;
  45. if (obj != null)
  46. _InstanceID = obj.GetInstanceID();
  47. }
  48. /************************************************************************************************************************/
  49. private void Initialize()
  50. {
  51. if (_Object == null)
  52. _Object = EditorUtility.InstanceIDToObject(_InstanceID);
  53. else
  54. _InstanceID = _Object.GetInstanceID();
  55. }
  56. /************************************************************************************************************************/
  57. /// <summary>
  58. /// Creates a new <see cref="ObjectReference"/> which wraps the specified
  59. /// <see cref="UnityEngine.Object"/>.
  60. /// </summary>
  61. public static implicit operator ObjectReference(Object obj)
  62. => new(obj);
  63. /// <summary>Returns the target <see cref="Object"/>.</summary>
  64. public static implicit operator Object(ObjectReference reference)
  65. => reference.Object;
  66. /************************************************************************************************************************/
  67. /// <summary>Creates a new array of <see cref="ObjectReference"/>s representing the `objects`.</summary>
  68. public static ObjectReference[] Convert(params Object[] objects)
  69. {
  70. var references = new ObjectReference[objects.Length];
  71. for (int i = 0; i < objects.Length; i++)
  72. references[i] = objects[i];
  73. return references;
  74. }
  75. /// <summary>
  76. /// Creates a new array of <see cref="UnityEngine.Object"/>s containing the target <see cref="Object"/> of each
  77. /// of the `references`.
  78. /// </summary>
  79. public static Object[] Convert(params ObjectReference[] references)
  80. {
  81. var objects = new Object[references.Length];
  82. for (int i = 0; i < references.Length; i++)
  83. objects[i] = references[i];
  84. return objects;
  85. }
  86. /************************************************************************************************************************/
  87. /// <summary>Indicates whether both arrays refer to the same set of objects.</summary>
  88. public static bool AreSameObjects(ObjectReference[] references, Object[] objects)
  89. {
  90. if (references == null)
  91. return objects == null;
  92. if (objects == null)
  93. return false;
  94. if (references.Length != objects.Length)
  95. return false;
  96. for (int i = 0; i < references.Length; i++)
  97. {
  98. if (references[i] != objects[i])
  99. return false;
  100. }
  101. return true;
  102. }
  103. /************************************************************************************************************************/
  104. /// <summary>Returns a string describing this object.</summary>
  105. public override string ToString()
  106. => $"Serialization.ObjectReference [{_InstanceID}] {_Object}";
  107. /************************************************************************************************************************/
  108. }
  109. /************************************************************************************************************************/
  110. /// <summary>Returns true if the `reference` and <see cref="ObjectReference.Object"/> are not null.</summary>
  111. public static bool IsValid(this ObjectReference reference)
  112. => reference?.Object != null;
  113. /************************************************************************************************************************/
  114. }
  115. }
  116. #endif