BikeAnimation.cs 4.9 KB

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