TimeSynchronizationGroup.cs 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. // Animancer // https://kybernetik.com.au/animancer // Copyright 2022 Kybernetik //
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. namespace Animancer
  5. {
  6. /// <summary>A system for synchronizing the <see cref="AnimancerState.NormalizedTime"/> of certain animations.</summary>
  7. /// <example>
  8. /// <list type="number">
  9. /// <item>Initialize a <see cref="TimeSynchronizationGroup"/> by adding any objects you want to synchronize.</item>
  10. /// <item>Call any of the <see cref="StoreTime(object)"/> methods before playing a new animation.</item>
  11. /// <item>Call any of the <see cref="SyncTime(object)"/> methods after playing that animation.</item>
  12. /// </list>
  13. /// Example: <see href="https://kybernetik.com.au/animancer/docs/examples/directional-sprites/character-controller#synchronization">Character Controller -> Synchronization</see>
  14. /// </example>
  15. /// https://kybernetik.com.au/animancer/api/Animancer/TimeSynchronizationGroup
  16. ///
  17. public class TimeSynchronizationGroup : HashSet<object>
  18. {
  19. /************************************************************************************************************************/
  20. private AnimancerComponent _Animancer;
  21. /// <summary>The <see cref="AnimancerComponent"/> this group is synchronizing.</summary>
  22. /// <remarks>
  23. /// This reference is not required if you always use the store and sync methods that take an
  24. /// <see cref="AnimancerState"/>.
  25. /// </remarks>
  26. public AnimancerComponent Animancer
  27. {
  28. get => _Animancer;
  29. set
  30. {
  31. _Animancer = value;
  32. NormalizedTime = null;
  33. }
  34. }
  35. /************************************************************************************************************************/
  36. /// <summary>The stored <see cref="AnimancerState.NormalizedTime"/> or <c>null</c> if no value was stored.</summary>
  37. public float? NormalizedTime { get; set; }
  38. /************************************************************************************************************************/
  39. /// <summary>Creates a new <see cref="TimeSynchronizationGroup"/> and sets its <see cref="Animancer"/>.</summary>
  40. public TimeSynchronizationGroup(AnimancerComponent animancer) => Animancer = animancer;
  41. /************************************************************************************************************************/
  42. /// <summary>
  43. /// Stores the <see cref="AnimancerState.NormalizedTime"/> of the <see cref="Animancer"/>'s current state if
  44. /// the `key` is in this group.
  45. /// </summary>
  46. public bool StoreTime(object key) => StoreTime(key, Animancer.States.Current);
  47. /// <summary>
  48. /// Stores the <see cref="AnimancerState.NormalizedTime"/> of the `state` if the `key` is in this group.
  49. /// </summary>
  50. public bool StoreTime(object key, AnimancerState state)
  51. {
  52. if (state != null && Contains(key))
  53. {
  54. NormalizedTime = state.NormalizedTime;
  55. return true;
  56. }
  57. else
  58. {
  59. NormalizedTime = null;
  60. return false;
  61. }
  62. }
  63. /************************************************************************************************************************/
  64. /// <summary>
  65. /// Applies the <see cref="NormalizedTime"/> to the <see cref="Animancer"/>'s current state if the `key` is in
  66. /// this group.
  67. /// </summary>
  68. public bool SyncTime(object key) => SyncTime(key, Time.deltaTime);
  69. /// <summary>
  70. /// Applies the <see cref="NormalizedTime"/> to the <see cref="Animancer"/>'s current state if the `key` is in
  71. /// this group.
  72. /// </summary>
  73. public bool SyncTime(object key, float deltaTime) => SyncTime(key, Animancer.States.Current, deltaTime);
  74. /// <summary>Applies the <see cref="NormalizedTime"/> to the `state` if the `key` is in this group.</summary>
  75. public bool SyncTime(object key, AnimancerState state) => SyncTime(key, state, Time.deltaTime);
  76. /// <summary>Applies the <see cref="NormalizedTime"/> to the `state` if the `key` is in this group.</summary>
  77. public bool SyncTime(object key, AnimancerState state, float deltaTime)
  78. {
  79. if (NormalizedTime == null ||
  80. state == null ||
  81. !Contains(key))
  82. return false;
  83. // Setting the Time forces it to stay at that value after the next animation update.
  84. // But we actually want it to keep playing, so we need to add deltaTime manually.
  85. state.Time = NormalizedTime.Value * state.Length + deltaTime * state.EffectiveSpeed;
  86. return true;
  87. }
  88. /************************************************************************************************************************/
  89. }
  90. }