BikeAnimation.cs 4.4 KB

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