BikeAnimation.cs 4.5 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 ??
  51. defaultCadence * bicycleController.CurrentSpeed / 8; //rpm
  52. var cadenceAngle = cadence / 60 * 360 * Time.deltaTime; //rps * 360 deg for one round
  53. RotateWheels();
  54. RotateAroundDefinedAxis(fork, bicycleController.CurrentSteerAngle);
  55. RotateAroundDefinedAxis(crankSet, cadenceAngle, false);
  56. }
  57. private void RotateWheels()
  58. {
  59. var speed = bicycleController.CurrentSpeed;
  60. var rps = speed / wheelCircumference;
  61. var angle = rps * Time.deltaTime * 360f;
  62. RotateSingleWheel(frontWheel, angle);
  63. RotateSingleWheel(rearWheel, angle);
  64. }
  65. private void RotateSingleWheel(WheelAnimationConfig wheel, float angle)
  66. {
  67. var t = wheel.wheel.transform;
  68. var oldPos = t.localPosition;
  69. var axis = wheel.rotationAxis;
  70. var backwards = wheel.rotationDirection == WheelRotationDirection.Backward;
  71. var directedAngle = backwards ? -angle : angle;
  72. Vector3 rotateAxis;
  73. if (axis == Axis.X)
  74. {
  75. rotateAxis = t.right;
  76. }
  77. else if (axis == Axis.Y)
  78. {
  79. rotateAxis = t.up;
  80. }
  81. else
  82. {
  83. rotateAxis = t.forward;
  84. }
  85. t.RotateAround(t.position, rotateAxis, directedAngle);
  86. t.localPosition = oldPos;
  87. }
  88. private void RotateAroundDefinedAxis(Rotatable rotatable, float angle, bool resetBeforeRotate = true)
  89. {
  90. if (resetBeforeRotate)
  91. {
  92. rotatable.gameObject.transform.localPosition = initialPositions[rotatable];
  93. rotatable.gameObject.transform.localRotation = initialRotations[rotatable];
  94. }
  95. Vector3 axis;
  96. if (rotatable.rotateAxis == RotateAxis.Up)
  97. axis = rotatable.rotateAround.up;
  98. else if (rotatable.rotateAxis == RotateAxis.Forward)
  99. axis = rotatable.rotateAround.forward;
  100. else
  101. axis = rotatable.rotateAround.right;
  102. rotatable.gameObject.transform.RotateAround(rotatable.rotateAround.position, axis, angle);
  103. }
  104. //rotates the meshes
  105. void RotateObject(GameObject obj, float multiplier)
  106. {
  107. obj.transform.Rotate(
  108. Time.deltaTime * bicycleController.CurrentSpeed * (360f / 12f) * multiplier, 0,
  109. 0);
  110. //obj.transform.Rotate(Time.deltaTime * rotSpeed * (360f / oneRotationSpeed) * multiplier, 0, 0);
  111. }
  112. }
  113. }