BikeAnimation.cs 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. using System;
  2. using System.Collections.Generic;
  3. using Controller;
  4. using Controller.Bicycle;
  5. using Sensors;
  6. using UnityEngine;
  7. namespace Animation
  8. {
  9. #region Helpers
  10. public enum WheelRotationAxis
  11. {
  12. X,
  13. Y,
  14. Z
  15. }
  16. public enum WheelRotationDirection
  17. {
  18. Forward,
  19. Backward
  20. }
  21. [Serializable]
  22. public struct WheelAnimationConfig
  23. {
  24. public GameObject wheel;
  25. public WheelRotationAxis rotationAxis;
  26. public WheelRotationDirection rotationDirection;
  27. }
  28. #endregion
  29. [RequireComponent(typeof(IBicycleController))]
  30. public class BikeAnimation : MonoBehaviour
  31. {
  32. #region Variables
  33. [Header("Wheels - rotating around center")]
  34. public WheelAnimationConfig rearWheel;
  35. public WheelAnimationConfig frontWheel;
  36. [Header("Other with defined rotation axis")]
  37. public Rotatable crankSet;
  38. public Rotatable fork;
  39. [Header("Parameters")] public float wheelCircumference = 2.096f;
  40. public float defaultCadence = 80;
  41. private IBicycleController bicycleController;
  42. private readonly Dictionary<Rotatable, Vector3> initialPositions = new Dictionary<Rotatable, Vector3>();
  43. private readonly Dictionary<Rotatable, Quaternion> initialRotations = new Dictionary<Rotatable, Quaternion>();
  44. #endregion
  45. // Start is called before the first frame update
  46. void Start()
  47. {
  48. bicycleController = GetComponentInParent<IBicycleController>();
  49. initialPositions[crankSet] = crankSet.gameObject.transform.localPosition;
  50. initialPositions[fork] = fork.gameObject.transform.localPosition;
  51. initialRotations[crankSet] = crankSet.gameObject.transform.localRotation;
  52. initialRotations[fork] = fork.gameObject.transform.localRotation;
  53. }
  54. void Update()
  55. {
  56. var cadence = BikeSensorData.Instance.PowermeterData?.InstantaneousCadence ?? defaultCadence; //rpm
  57. var cadenceAngle = cadence / 60 * 360 * Time.deltaTime; //rps * 360 deg for one round
  58. RotateWheels();
  59. RotateAroundDefinedAxis(fork, bicycleController.CurrentSteerAngle);
  60. RotateAroundDefinedAxis(crankSet, cadenceAngle, false);
  61. }
  62. private void RotateWheels()
  63. {
  64. var speed = bicycleController.CurrentSpeed;
  65. var rps = speed / wheelCircumference;
  66. var angle = rps * Time.deltaTime * 360f;
  67. RotateSingleWheel(frontWheel, angle);
  68. RotateSingleWheel(rearWheel, angle);
  69. }
  70. private void RotateSingleWheel(WheelAnimationConfig wheel, float angle)
  71. {
  72. var t = wheel.wheel.transform;
  73. var oldPos = t.localPosition;
  74. var axis = wheel.rotationAxis;
  75. var backwards = wheel.rotationDirection == WheelRotationDirection.Backward;
  76. var directedAngle = backwards ? -angle : angle;
  77. Vector3 rotateAxis;
  78. if (axis == WheelRotationAxis.X)
  79. {
  80. rotateAxis = t.right;
  81. }
  82. else if (axis == WheelRotationAxis.Y)
  83. {
  84. rotateAxis = t.up;
  85. }
  86. else
  87. {
  88. rotateAxis = t.forward;
  89. }
  90. t.RotateAround(t.position, rotateAxis, directedAngle);
  91. t.localPosition = oldPos;
  92. }
  93. private void RotateAroundDefinedAxis(Rotatable rotatable, float angle, bool resetBeforeRotate = true)
  94. {
  95. if (resetBeforeRotate)
  96. {
  97. rotatable.gameObject.transform.localPosition = initialPositions[rotatable];
  98. rotatable.gameObject.transform.localRotation = initialRotations[rotatable];
  99. }
  100. Vector3 axis;
  101. if (rotatable.rotateAxis == RotateAxis.Up)
  102. axis = rotatable.rotateAround.up;
  103. else if (rotatable.rotateAxis == RotateAxis.Forward)
  104. axis = rotatable.rotateAround.forward;
  105. else
  106. axis = rotatable.rotateAround.right;
  107. fork.gameObject.transform.RotateAround(rotatable.rotateAround.position, axis, angle);
  108. }
  109. //rotates the meshes
  110. void RotateObject(GameObject obj, float multiplier)
  111. {
  112. obj.transform.Rotate(
  113. Time.deltaTime * bicycleController.CurrentSpeed * (360f / 12f) * multiplier, 0,
  114. 0);
  115. //obj.transform.Rotate(Time.deltaTime * rotSpeed * (360f / oneRotationSpeed) * multiplier, 0, 0);
  116. }
  117. }
  118. }