SerializedComponentDataEditorWindow.cs 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. // Animancer // Copyright 2018-2024 Kybernetik //
  2. #if UNITY_EDITOR
  3. using System;
  4. using UnityEditor;
  5. using UnityEngine;
  6. namespace Animancer.Editor
  7. {
  8. /// <summary>[Editor-Only]
  9. /// A <see cref="SerializedDataEditorWindow{TObject, TData}"/> for <see cref="Component"/>s.
  10. /// </summary>
  11. /// https://kybernetik.com.au/animancer/api/Animancer.Editor/SerializedComponentDataEditorWindow_2
  12. public abstract class SerializedComponentDataEditorWindow<TObject, TData> :
  13. SerializedDataEditorWindow<TObject, TData>
  14. where TObject : Component
  15. where TData : class, ICopyable<TData>, IEquatable<TData>, new()
  16. {
  17. /************************************************************************************************************************/
  18. [SerializeField] private GameObject _SourceGameObject;
  19. [SerializeField] private int _SourceComponentInstanceID;
  20. /************************************************************************************************************************/
  21. /// <inheritdoc/>
  22. public override TObject SourceObject
  23. {
  24. get
  25. {
  26. // For whatever reason, component references in an EditorWindow can't survive entering Play Mode but
  27. // a GameObject or Transform reference can so we use that to recover the component.
  28. // Storing the Instance ID also works, but seems to also survive restarting the Unity Editor which is
  29. // bad because the scene references inside the data don't survive that which would leave us
  30. // with an open window full of empty references. Working around that isn't worth the effort.
  31. // So if the GameObject still exists, we use the Component's Instance ID to find it.
  32. var source = base.SourceObject;
  33. if (source == null && _SourceGameObject != null)
  34. source = base.SourceObject = EditorUtility.InstanceIDToObject(_SourceComponentInstanceID) as TObject;
  35. return source;
  36. }
  37. }
  38. /************************************************************************************************************************/
  39. /// <inheritdoc/>
  40. public override bool SourceObjectMightBePrefab
  41. => true;
  42. /************************************************************************************************************************/
  43. /// <inheritdoc/>
  44. protected override void CaptureData()
  45. {
  46. base.CaptureData();
  47. if (SourceObject != null)
  48. {
  49. _SourceGameObject = SourceObject.gameObject;
  50. _SourceComponentInstanceID = SourceObject.GetInstanceID();
  51. }
  52. }
  53. /************************************************************************************************************************/
  54. }
  55. }
  56. #endif