SceneBuilder.Animations.cs 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using BabylonExport.Entities;
  6. using UnityEditor;
  7. using UnityEditor.Animations;
  8. using UnityEngine;
  9. namespace Unity3D2Babylon
  10. {
  11. partial class SceneBuilder
  12. {
  13. private static void ExportAnimations(Transform transform, BabylonIAnimatable animatable)
  14. {
  15. var animator = transform.gameObject.GetComponent<Animator>();
  16. if (animator != null)
  17. {
  18. AnimatorController ac = animator.runtimeAnimatorController as AnimatorController;
  19. if (ac == null)
  20. {
  21. return;
  22. }
  23. var layer = ac.layers[0];
  24. if (layer == null)
  25. {
  26. return;
  27. }
  28. AnimatorStateMachine sm = layer.stateMachine;
  29. if (sm.states.Length > 0)
  30. {
  31. var state = sm.states[0].state; // We only support the first one
  32. AnimationClip clip = state.motion as AnimationClip;
  33. if (clip != null)
  34. {
  35. ExportAnimationClip(clip, true, animatable);
  36. }
  37. }
  38. }
  39. else
  40. {
  41. var animation = transform.gameObject.GetComponent<Animation>();
  42. if (animation != null && animation.clip != null)
  43. {
  44. ExportAnimationClip(animation.clip, animation.playAutomatically, animatable);
  45. }
  46. }
  47. }
  48. private static bool IsRotationQuaternionAnimated(BabylonIAnimatable animatable)
  49. {
  50. if (animatable.animations == null)
  51. {
  52. return false;
  53. }
  54. return animatable.animations.Any(animation => animation.property.Contains("rotationQuaternion"));
  55. }
  56. private static void ExportAnimationClip(AnimationClip clip, bool autoPlay, BabylonIAnimatable animatable)
  57. {
  58. var curveBindings = AnimationUtility.GetCurveBindings(clip);
  59. var animations = new List<BabylonAnimation>();
  60. var maxFrame = 0;
  61. foreach (var binding in curveBindings)
  62. {
  63. var curve = AnimationUtility.GetEditorCurve(clip, binding);
  64. string property;
  65. switch (binding.propertyName)
  66. {
  67. case "m_LocalPosition.x":
  68. property = "position.x";
  69. break;
  70. case "m_LocalPosition.y":
  71. property = "position.y";
  72. break;
  73. case "m_LocalPosition.z":
  74. property = "position.z";
  75. break;
  76. case "m_LocalRotation.x":
  77. property = "rotationQuaternion.x";
  78. break;
  79. case "m_LocalRotation.y":
  80. property = "rotationQuaternion.y";
  81. break;
  82. case "m_LocalRotation.z":
  83. property = "rotationQuaternion.z";
  84. break;
  85. case "m_LocalRotation.w":
  86. property = "rotationQuaternion.w";
  87. break;
  88. case "m_LocalScale.x":
  89. property = "scaling.x";
  90. break;
  91. case "m_LocalScale.y":
  92. property = "scaling.y";
  93. break;
  94. case "m_LocalScale.z":
  95. property = "scaling.z";
  96. break;
  97. default:
  98. continue;
  99. }
  100. var babylonAnimation = new BabylonAnimation
  101. {
  102. dataType = (int)BabylonAnimation.DataType.Float,
  103. name = property + " animation",
  104. keys = curve.keys.Select(keyFrame => new BabylonAnimationKey
  105. {
  106. frame = (int)(keyFrame.time * clip.frameRate),
  107. values = new[] { keyFrame.value }
  108. }).ToArray(),
  109. framePerSecond = (int)clip.frameRate,
  110. loopBehavior = (int)BabylonAnimation.LoopBehavior.Cycle,
  111. property = property
  112. };
  113. maxFrame = Math.Max(babylonAnimation.keys.Last().frame, maxFrame);
  114. animations.Add(babylonAnimation);
  115. }
  116. if (animations.Count > 0)
  117. {
  118. animatable.animations = animations.ToArray();
  119. if (autoPlay)
  120. {
  121. animatable.autoAnimate = true;
  122. animatable.autoAnimateFrom = 0;
  123. animatable.autoAnimateTo = maxFrame;
  124. animatable.autoAnimateLoop = clip.isLooping;
  125. }
  126. }
  127. }
  128. }
  129. }