GenericPoser.cs 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. using UnityEngine;
  2. using System.Collections;
  3. using System;
  4. namespace RootMotion.FinalIK {
  5. /// <summary>
  6. /// Posing the children of a Transform to match the children of another Transform
  7. /// </summary>
  8. public class GenericPoser : Poser {
  9. /// <summary>
  10. /// Mapping a bone to it's target
  11. /// </summary>
  12. [System.Serializable]
  13. public class Map {
  14. public Transform bone;
  15. public Transform target;
  16. private Vector3 defaultLocalPosition;
  17. private Quaternion defaultLocalRotation;
  18. // Custom constructor
  19. public Map(Transform bone, Transform target) {
  20. this.bone = bone;
  21. this.target = target;
  22. StoreDefaultState();
  23. }
  24. public void StoreDefaultState() {
  25. defaultLocalPosition = bone.localPosition;
  26. defaultLocalRotation = bone.localRotation;
  27. }
  28. public void FixTransform() {
  29. bone.localPosition = defaultLocalPosition;
  30. bone.localRotation = defaultLocalRotation;
  31. }
  32. // Update mapping
  33. public void Update(float localRotationWeight, float localPositionWeight) {
  34. bone.localRotation = Quaternion.Lerp(bone.localRotation, target.localRotation, localRotationWeight);
  35. bone.localPosition = Vector3.Lerp(bone.localPosition, target.localPosition, localPositionWeight);
  36. }
  37. }
  38. public Map[] maps;
  39. /// <summary>
  40. /// Finds mapping automatically. This requires for all children of the transform to have unique names. This method is not very memory efficient so try to avoid using it in play mode.
  41. /// </summary>
  42. [ContextMenu("Auto-Mapping")]
  43. public override void AutoMapping() {
  44. if (poseRoot == null) {
  45. maps = new Map[0];
  46. return;
  47. }
  48. maps = new Map[0];
  49. Transform[] children = (Transform[])transform.GetComponentsInChildren<Transform>();
  50. Transform[] poseChildren = (Transform[])poseRoot.GetComponentsInChildren<Transform>();
  51. Transform target;
  52. // Find all the bone to target matches
  53. for (int i = 1; i < children.Length; i++) {
  54. target = GetTargetNamed(children[i].name, poseChildren);
  55. if (target != null) {
  56. Array.Resize(ref maps, maps.Length + 1);
  57. maps[maps.Length - 1] = new Map(children[i], target);
  58. }
  59. }
  60. StoreDefaultState();
  61. }
  62. protected override void InitiatePoser() {
  63. StoreDefaultState();
  64. }
  65. protected override void UpdatePoser() {
  66. if (weight <= 0f) return;
  67. if (localPositionWeight <= 0f && localRotationWeight <= 0f) return;
  68. if (poseRoot == null) return;
  69. // Calculate weights
  70. float rW = localRotationWeight * weight;
  71. float pW = localPositionWeight * weight;
  72. // Lerping the localRotation and the localPosition
  73. for (int i = 0; i < maps.Length; i++) maps[i].Update(rW, pW);
  74. }
  75. protected override void FixPoserTransforms() {
  76. for (int i = 0; i < maps.Length; i++) {
  77. maps[i].FixTransform();
  78. }
  79. }
  80. private void StoreDefaultState() {
  81. for (int i = 0; i < maps.Length; i++) {
  82. maps[i].StoreDefaultState();
  83. }
  84. }
  85. // Returns a Transform from the array that has the specified name
  86. private Transform GetTargetNamed(string tName, Transform[] array) {
  87. for (int i = 0; i < array.Length; i++) {
  88. if (array[i].name == tName) return array[i];
  89. }
  90. return null;
  91. }
  92. }
  93. }