BikeAnimation.cs 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  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. public bool pause = false; //TODO: remove, only for debugging purposes
  28. [Header("Wheels - rotating around center")]
  29. public WheelAnimationConfig rearWheel;
  30. public WheelAnimationConfig frontWheel;
  31. [Header("Other with defined rotation axis")]
  32. public Rotatable crankSet;
  33. public Rotatable fork;
  34. [Header("Parameters")] public float wheelCircumference = 2.096f;
  35. public float defaultCadence = 80;
  36. private IBicycleController bicycleController;
  37. private readonly Dictionary<Rotatable, Vector3> initialPositions = new Dictionary<Rotatable, Vector3>();
  38. private readonly Dictionary<Rotatable, Quaternion> initialRotations = new Dictionary<Rotatable, Quaternion>();
  39. #endregion
  40. // Start is called before the first frame update
  41. void Start()
  42. {
  43. bicycleController = GetComponentInParent<IBicycleController>();
  44. initialPositions[crankSet] = crankSet.gameObject.transform.localPosition;
  45. initialPositions[fork] = fork.gameObject.transform.localPosition;
  46. initialRotations[crankSet] = crankSet.gameObject.transform.localRotation;
  47. initialRotations[fork] = fork.gameObject.transform.localRotation;
  48. }
  49. void Update()
  50. {
  51. var cadence = /*BikeSensorData.Instance.PowermeterData?.InstantaneousCadence ??*/
  52. defaultCadence * bicycleController.CurrentSpeed / 8; //rpm*/
  53. var cadenceAngle = cadence / 60 * 360 * Time.deltaTime; //rps * 360 deg for one round
  54. if (!pause)
  55. {
  56. RotateWheels();
  57. RotateAroundDefinedAxis(fork, bicycleController.CurrentSteerAngle);
  58. //Debug.Log($"Rotate cranks with angle {cadenceAngle}");
  59. RotateAroundDefinedAxis(crankSet, cadenceAngle, false);
  60. }
  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 == Axis.X)
  79. {
  80. rotateAxis = t.right;
  81. }
  82. else if (axis == Axis.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. if (Mathf.Abs(angle) <= 0.2f) return;
  101. Vector3 axis;
  102. if (rotatable.rotateAxis == RotateAxis.Up)
  103. axis = rotatable.rotateAround.up;
  104. else if (rotatable.rotateAxis == RotateAxis.Forward)
  105. axis = rotatable.rotateAround.forward;
  106. else
  107. axis = rotatable.rotateAround.right;
  108. //Debug.Log($"rotatable.rotateAround.position = {rotatable.rotateAround.position}");
  109. //Debug.Log($"axis = {axis}");
  110. //Debug.DrawLine(rotatable.rotateAround.position, rotatable.rotateAround.position+axis*5, Color.yellow);
  111. rotatable.gameObject.transform.RotateAround(rotatable.rotateAround.position, axis, angle);
  112. }
  113. //rotates the meshes
  114. void RotateObject(GameObject obj, float multiplier)
  115. {
  116. obj.transform.Rotate(
  117. Time.deltaTime * bicycleController.CurrentSpeed * (360f / 12f) * multiplier, 0,
  118. 0);
  119. //obj.transform.Rotate(Time.deltaTime * rotSpeed * (360f / oneRotationSpeed) * multiplier, 0, 0);
  120. }
  121. }
  122. }