DynamicReductionSource.cs 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. using System;
  2. using Controller.Bicycle;
  3. using SicknessReduction.Visual.Vignetting;
  4. using UnityEngine;
  5. using UnityEngine.Serialization;
  6. using Wheels;
  7. namespace SicknessReduction
  8. {
  9. public class DynamicReductionSource : MonoBehaviour
  10. {
  11. #region vars
  12. private const float MAX_SLOPE_ANGLE = 8.531f;
  13. public RbBicycleController bikeController;
  14. public LerpSlopeCollider slopeCollider;
  15. [Header("Configuration")] public bool useSpeed = true;
  16. public bool useSteer = true;
  17. public bool useSlope = true;
  18. public float minSpeedForRestriction = 0.28f;
  19. public float speedMultiplier = 1f;
  20. public float slopeMultiplier = 1f;
  21. public float steerMultiplier = 1f;
  22. [Header("Restriction Data")] public float minValue = 0.3f;
  23. public float maxValue = 0.7f;
  24. public float maxValueChangePerSecond = 0.8f;
  25. [FormerlySerializedAs("threshold")] [Tooltip("Depending on Vignetting source -> deg or deg/s")]
  26. public float steerThreshold = 20f;
  27. public float speedThreshold = 1f;
  28. public float slopeThreshold = 1f;
  29. private float currentSlopeDeg;
  30. private ValueBasedRestrictionSuggestor steerAngleSuggestor;
  31. private ValueBasedRestrictionSuggestor slopeSuggestor;
  32. private ValueAndTimeBasedRestrictionSuggestor speedSuggestor;
  33. protected float currentValue;
  34. public float CurrentValue => currentValue;
  35. #endregion
  36. protected virtual void Start()
  37. {
  38. if (bikeController == null) Debug.LogError("bike controller = null!");
  39. if (useSteer)
  40. steerAngleSuggestor =
  41. new ValueBasedRestrictionSuggestor(steerThreshold, minValue, maxValue,
  42. bikeController.maxSteeringAngle); //deg
  43. if (useSpeed)
  44. speedSuggestor = new ValueAndTimeBasedRestrictionSuggestor(speedThreshold, minValue,
  45. maxValue, 25f, 1.111f /*4kmh*/, 3);
  46. if (useSlope)
  47. {
  48. slopeCollider.OnSlopeChanged += (timestamp, slope) => currentSlopeDeg = slope;
  49. slopeSuggestor =
  50. new ValueBasedRestrictionSuggestor(slopeThreshold, minValue, maxValue, MAX_SLOPE_ANGLE);
  51. }
  52. }
  53. protected virtual void Update()
  54. {
  55. if (bikeController.CurrentSpeed < minSpeedForRestriction)
  56. {
  57. currentValue = 0;
  58. return;
  59. }
  60. if (useSteer) steerAngleSuggestor.Value = bikeController.CurrentSteerAngle;
  61. if (useSpeed) speedSuggestor.UpdateValue(bikeController.CurrentSpeed);
  62. if (useSlope) slopeSuggestor.Value = currentSlopeDeg;
  63. var steerSuggestion = useSteer ? steerAngleSuggestor.Suggestion * steerMultiplier : 0f;
  64. var speedSuggestion = useSpeed ? speedSuggestor.Suggestion * speedMultiplier : 0f;
  65. var slopeSuggestion = useSlope ? slopeSuggestor.Suggestion * slopeMultiplier : 0f;
  66. var maxSuggestion = Mathf.Max(steerSuggestion, speedSuggestion, slopeSuggestion);
  67. if (Math.Abs(maxSuggestion - steerSuggestion) < 0.01f)
  68. {
  69. Debug.Log("Suggestion won by Steer");
  70. }else if (Math.Abs(maxSuggestion - speedSuggestion) < 0.01f)
  71. {
  72. Debug.Log("Suggestion won by Speed");
  73. }else if (Math.Abs(maxSuggestion - slopeSuggestion) < 0.01f)
  74. {
  75. Debug.Log("Suggestion won by Slope");
  76. }
  77. var desiredValue = Mathf.Min(maxSuggestion, maxValue);
  78. var desiredChange = desiredValue - currentValue;
  79. var maxChange = Time.deltaTime * maxValueChangePerSecond;
  80. var change = Mathf.Sign(desiredChange) * Mathf.Min(Mathf.Abs(desiredChange), maxChange);
  81. currentValue = Mathf.Clamp(currentValue + change, 0, 1);
  82. Debug.Log($"SuggestionValue = {currentValue}");
  83. }
  84. }
  85. }