RbBicycleSlopeSpeedManager.cs 3.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. using System;
  2. using Controller.Bicycle;
  3. using UnityEngine;
  4. using Wheels;
  5. namespace Phscs
  6. {
  7. [RequireComponent(typeof(RbBicycleController))]
  8. public class RbBicycleSlopeSpeedManager : MonoBehaviour
  9. {
  10. [Header("Game Objects")] public LerpSlopeCollider slopeCollider;
  11. private RbBicycleController bicycleController;
  12. [Header("Linear Adjustment")] [Range(0, 3)]
  13. public float speedFactorUphill;
  14. [Range(0, 3)] public float speedFactorDownhill;
  15. [Header("Lerp time at slope changes")] public float lerpTimeUphillStart; //TODO: maybe as factor of speed
  16. public float lerpTimeUphillEnd;
  17. public float lerpTimeDownhillStart;
  18. public float lerpTimeDownhillEnd;
  19. private const float THRESHOLD = 0.05f;
  20. private const float SLOPE_CHANGE_THRESHOLD = 2f;
  21. private float t0;
  22. private float v0;
  23. private readonly float g = UnityEngine.Physics.gravity.y;
  24. private float alpha;
  25. private float alphaBefore;
  26. private int direction;
  27. private int directionBefore;
  28. public float? AdjustedSpeed { private set; get; }
  29. private void Start()
  30. {
  31. bicycleController = GetComponent<RbBicycleController>();
  32. slopeCollider.OnSlopeChanged += delegate(float timestamp, float slopeDeg)
  33. {
  34. alphaBefore = alpha;
  35. alpha = slopeDeg;
  36. if (Mathf.Abs(alphaBefore - alpha) < SLOPE_CHANGE_THRESHOLD) return;
  37. t0 = timestamp;
  38. v0 = bicycleController.CurrentSpeed;
  39. directionBefore = direction;
  40. };
  41. }
  42. private void OnGUI()
  43. {
  44. GUI.TextField(new Rect(150, 10, 200, 20), $"direction: {direction}, directionBefore: {directionBefore}");
  45. }
  46. private void FixedUpdate()
  47. {
  48. direction = Math.Abs(alpha) > THRESHOLD ? slopeCollider.SlopeDirection : 0;
  49. if (direction == 0 && directionBefore == 0)
  50. {
  51. AdjustedSpeed = null;
  52. return;
  53. }
  54. var t = Time.fixedTime - t0;
  55. var gradient = Mathf.Tan(direction * alpha * Mathf.Deg2Rad);
  56. var gradientBefore = Mathf.Tan(directionBefore * alphaBefore * Mathf.Deg2Rad);
  57. var mass = bicycleController.rigidBody.mass;
  58. float calculatedSpeed;
  59. var sensedSpeed = bicycleController.CurrentSpeedSensed;
  60. if (directionBefore == 0 && direction == 1) //flat to uphill
  61. {
  62. calculatedSpeed = BicyclePhysics.SpeedAtGradientForSpeedAtFlat(sensedSpeed, mass, gradient) * speedFactorUphill;
  63. AdjustedSpeed = Mathf.Lerp(sensedSpeed, calculatedSpeed, t / lerpTimeUphillStart);
  64. }
  65. else if (directionBefore == 1 && direction == 0) //uphill to flat
  66. {
  67. calculatedSpeed = BicyclePhysics.SpeedAtGradientForSpeedAtFlat(sensedSpeed, mass, gradientBefore) * speedFactorUphill;
  68. AdjustedSpeed = Mathf.Lerp(calculatedSpeed, sensedSpeed , t / lerpTimeUphillEnd);
  69. }
  70. else if (directionBefore == 0 && direction == -1) //flat to downhill
  71. {
  72. calculatedSpeed = BicyclePhysics.SpeedAtGradientForSpeedAtFlat(sensedSpeed, mass, gradient) * speedFactorDownhill;
  73. AdjustedSpeed = Mathf.Lerp(sensedSpeed, calculatedSpeed, t / lerpTimeDownhillStart);
  74. }
  75. else if (directionBefore == -1 && direction == 0) //downhill to flat
  76. {
  77. calculatedSpeed = BicyclePhysics.SpeedAtGradientForSpeedAtFlat(sensedSpeed, mass, gradientBefore) * speedFactorDownhill;
  78. AdjustedSpeed = Mathf.Lerp(calculatedSpeed, sensedSpeed, t / lerpTimeDownhillEnd);
  79. }
  80. }
  81. }
  82. }