SerializedArrayProperty.cs 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. // Animancer // https://kybernetik.com.au/animancer // Copyright 2018-2024 Kybernetik //
  2. #if UNITY_EDITOR
  3. using UnityEditor;
  4. namespace Animancer.Editor
  5. {
  6. /// <summary>[Editor-Only] A wrapper around a <see cref="SerializedProperty"/> representing an array field.</summary>
  7. public class SerializedArrayProperty
  8. {
  9. /************************************************************************************************************************/
  10. private SerializedProperty _Property;
  11. /// <summary>The target property.</summary>
  12. public SerializedProperty Property
  13. {
  14. get => _Property;
  15. set
  16. {
  17. _Property = value;
  18. Refresh();
  19. }
  20. }
  21. /************************************************************************************************************************/
  22. private string _Path;
  23. /// <summary>The cached <see cref="SerializedProperty.propertyPath"/> of the <see cref="Property"/>.</summary>
  24. public string Path => _Path ?? (_Path = Property.propertyPath);
  25. /************************************************************************************************************************/
  26. private int _Count;
  27. /// <summary>The cached <see cref="SerializedProperty.arraySize"/> of the <see cref="Property"/>.</summary>
  28. public int Count
  29. {
  30. get => _Count;
  31. set => Property.arraySize = _Count = value;
  32. }
  33. /************************************************************************************************************************/
  34. private bool _HasMultipleDifferentValues;
  35. private bool _GotHasMultipleDifferentValues;
  36. /// <summary>The cached <see cref="SerializedProperty.hasMultipleDifferentValues"/> of the <see cref="Property"/>.</summary>
  37. public bool HasMultipleDifferentValues
  38. {
  39. get
  40. {
  41. if (!_GotHasMultipleDifferentValues)
  42. {
  43. _GotHasMultipleDifferentValues = true;
  44. _HasMultipleDifferentValues = Property.hasMultipleDifferentValues;
  45. }
  46. return _HasMultipleDifferentValues;
  47. }
  48. }
  49. /************************************************************************************************************************/
  50. /// <summary>Updates the cached <see cref="Count"/> and <see cref="HasMultipleDifferentValues"/>.</summary>
  51. public void Refresh()
  52. {
  53. _Path = null;
  54. _Count = _Property != null ? _Property.arraySize : 0;
  55. _GotHasMultipleDifferentValues = false;
  56. }
  57. /************************************************************************************************************************/
  58. /// <summary>Calls <see cref="SerializedProperty.GetArrayElementAtIndex"/> on the <see cref="Property"/>.</summary>
  59. /// <remarks>
  60. /// Returns <c>null</c> if the element is not actually a child of the <see cref="Property"/>, which can happen
  61. /// if multiple objects are selected with different array sizes.
  62. /// </remarks>
  63. public SerializedProperty GetElement(int index)
  64. {
  65. var element = Property.GetArrayElementAtIndex(index);
  66. if (!HasMultipleDifferentValues || element.propertyPath.StartsWith(Path))
  67. return element;
  68. else
  69. return null;
  70. }
  71. /************************************************************************************************************************/
  72. }
  73. }
  74. #endif