Damping.cs 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. // Animancer // https://kybernetik.com.au/animancer // Copyright 2022 Kybernetik //
  2. #pragma warning disable CS0649 // Field is never assigned to, and will always have its default value.
  3. using Unity.Collections;
  4. using UnityEngine;
  5. using UnityEngine.Animations;
  6. namespace Animancer.Examples.Jobs
  7. {
  8. /// <summary>An example of how to use Animation Jobs in Animancer to apply physics based damping to certain bones.</summary>
  9. ///
  10. /// <remarks>
  11. /// This example is based on Unity's
  12. /// <see href="https://github.com/Unity-Technologies/animation-jobs-samples">Animation Jobs Samples</see>.
  13. /// <para></para>
  14. /// This script sets up the job in place of
  15. /// <see href="https://github.com/Unity-Technologies/animation-jobs-samples/blob/master/Assets/animation-jobs-samples/Samples/Scripts/Damping/Damping.cs">
  16. /// Damping.cs</see>.
  17. /// <para></para>
  18. /// The <see cref="DampingJob"/> script is almost identical to the original
  19. /// <see href="https://github.com/Unity-Technologies/animation-jobs-samples/blob/master/Assets/animation-jobs-samples/Runtime/AnimationJobs/DampingJob.cs">
  20. /// DampingJob.cs</see>.
  21. /// <para></para>
  22. /// The <see href="https://learn.unity.com/tutorial/working-with-animation-rigging">Animation Rigging</see> package
  23. /// has a damping system which is likely better than this example.
  24. /// </remarks>
  25. ///
  26. /// <example><see href="https://kybernetik.com.au/animancer/docs/examples/jobs/damping">Damping</see></example>
  27. ///
  28. /// https://kybernetik.com.au/animancer/api/Animancer.Examples.Jobs/Damping
  29. ///
  30. [AddComponentMenu(Strings.ExamplesMenuPrefix + "Jobs - Damping")]
  31. [HelpURL(Strings.DocsURLs.ExampleAPIDocumentation + nameof(Jobs) + "/" + nameof(Damping))]
  32. public sealed class Damping : MonoBehaviour
  33. {
  34. /************************************************************************************************************************/
  35. [SerializeField] private AnimancerComponent _Animancer;
  36. [SerializeField] private Transform _EndBone;
  37. [SerializeField] private int _BoneCount = 1;
  38. /************************************************************************************************************************/
  39. private void Awake()
  40. {
  41. // Create the job and initialize all its arrays.
  42. // They are all Persistent because we want them to last for the full lifetime of the job.
  43. // Most of them can use UninitializedMemory which is faster because we will be immediately filling them.
  44. // But the velocities will use the default ClearMemory to make sure all the values start at zero.
  45. // Since we are about to use these values several times, we can shorten the following lines a bit by using constants:
  46. const Allocator Persistent = Allocator.Persistent;
  47. const NativeArrayOptions UninitializedMemory = NativeArrayOptions.UninitializedMemory;
  48. var job = new DampingJob()
  49. {
  50. jointHandles = new NativeArray<TransformStreamHandle>(_BoneCount, Persistent, UninitializedMemory),
  51. localPositions = new NativeArray<Vector3>(_BoneCount, Persistent, UninitializedMemory),
  52. localRotations = new NativeArray<Quaternion>(_BoneCount, Persistent, UninitializedMemory),
  53. positions = new NativeArray<Vector3>(_BoneCount, Persistent, UninitializedMemory),
  54. velocities = new NativeArray<Vector3>(_BoneCount, Persistent),
  55. };
  56. // Initialize the contents of the arrays for each bone.
  57. var animator = _Animancer.Animator;
  58. var bone = _EndBone;
  59. for (int i = _BoneCount - 1; i >= 0; i--)
  60. {
  61. job.jointHandles[i] = animator.BindStreamTransform(bone);
  62. job.localPositions[i] = bone.localPosition;
  63. job.localRotations[i] = bone.localRotation;
  64. job.positions[i] = bone.position;
  65. bone = bone.parent;
  66. }
  67. job.rootHandle = animator.BindStreamTransform(bone);
  68. // Add the job to Animancer's output.
  69. _Animancer.Playable.InsertOutputJob(job);
  70. // Make sure Animancer disposes the Native Arrays when it is destroyed so we don't leak memory.
  71. // If we were writing our own job rather than just using the sample, we could have it implement the
  72. // IDisposable interface to dispose its arrays so that we would only have to call ...Add(_Job); here.
  73. _Animancer.Playable.Disposables.Add(job.jointHandles);
  74. _Animancer.Playable.Disposables.Add(job.localPositions);
  75. _Animancer.Playable.Disposables.Add(job.localRotations);
  76. _Animancer.Playable.Disposables.Add(job.positions);
  77. _Animancer.Playable.Disposables.Add(job.velocities);
  78. }
  79. /************************************************************************************************************************/
  80. /// <summary>
  81. /// Ensures that the <see cref="_BoneCount"/> is positive and not larger than the number of bones between the
  82. /// <see cref="_EndBone"/> and the <see cref="Animator"/>.
  83. /// </summary>
  84. /// <remarks>Called in Edit Mode whenever this script is loaded or a value is changed in the Inspector.</remarks>
  85. private void OnValidate()
  86. {
  87. if (_BoneCount < 1)
  88. {
  89. _BoneCount = 1;
  90. }
  91. else if (_EndBone != null && _Animancer != null && _Animancer.Animator != null)
  92. {
  93. var root = _Animancer.Animator.transform;
  94. var bone = _EndBone;
  95. for (int i = 0; i < _BoneCount; i++)
  96. {
  97. bone = bone.parent;
  98. if (bone == root)
  99. {
  100. _BoneCount = i + 1;
  101. break;
  102. }
  103. else if (bone == null)
  104. {
  105. _EndBone = null;
  106. Debug.LogWarning("The End Bone must be a child of the Animator.");
  107. break;
  108. }
  109. }
  110. }
  111. }
  112. /************************************************************************************************************************/
  113. }
  114. }