123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123 |
- using System;
- using System.Collections.Generic;
- using UnityEngine;
- namespace Controller.Bicycle
- {
- internal readonly struct Booster
- {
- public float StartTime { get; }
- public float EndTime { get; }
- public float StartValue { get; }
- public float EndValue { get; }
- public Booster(float startTime, float duration, float startValue, float endValue)
- {
- StartTime = startTime;
- EndTime = startTime + duration;
- StartValue = startValue;
- EndValue = endValue;
- }
- public override string ToString()
- {
- return $"Booster({StartValue}-{EndValue} between Time({StartTime}, {EndTime}))";
- }
- }
- public class BikeSpeedBooster
- {
- public const float MaxBoost = 1.4f;
- public const float MinBoost = 0.6f;
- public const float ThresholdZero = 0.05f;
- private const float DURATION_BOOST_STRAIGHT_UPHILL = 2.5f;
- private const float DURATION_BOOST_UPHILL_STRAIGHT = 1.5f;
- private const float DURATION_BOOST_STRAIGHT_DOWNHILL = 3.5f;
- private const float DURATION_BOOST_DOWNHILL_STRAIGHT = 5f;
- private float fixedBoost = 1;
- private readonly float maxSlopeDeg = 8.7f;
- public float Boost
- {
- get
- {
- var boost = fixedBoost;
- var toDelete = new Stack<Booster>();
- var t = Time.time;
- foreach (var b in activeBooster)
- {
- if (b.EndTime < t)
- {
- toDelete.Push(b);
- continue;
- }
- if (b.StartTime > t) continue;
- var add = Mathf.Lerp(b.StartValue, b.EndValue,
- (Time.time - b.StartTime) / (b.EndTime - b.StartTime));
- boost *= add;
- }
- foreach (var d in toDelete) activeBooster.Remove(d);
- return Mathf.Clamp(boost, MinBoost, MaxBoost);
- }
- }
- public void AddBoosterForFirstAndSlope(float slopeDegree)
- {
- //going from straight to downhill -> increase speed from straight to slope
- //-> inverse fixed boost first, then 1*fixedBoost
- //going from straight to uphill -> decrease speed from straight to slope
- //-> inverse fixed boost first, then 1*fixedBoost
- var booster = new Booster(Time.time,
- slopeDegree < 0 ? DURATION_BOOST_STRAIGHT_DOWNHILL : DURATION_BOOST_STRAIGHT_UPHILL,
- 1f / fixedBoost, 1f);
- //Debug.Log($"Adding Booster: {booster}");
- activeBooster.Add(booster);
- }
- public void AddBoosterForLastAndSlope(float slopeDegree)
- {
- //going from downhill to straight -> let the bike roll -> boost starts at fixedBoost and decreases to 1
- //going from uphill to straight -> don't go to 1 immediately
- //-> boost starts at fixedBoost and increases to 1
- var booster = new Booster(Time.time,
- slopeDegree < 0 ? DURATION_BOOST_DOWNHILL_STRAIGHT : DURATION_BOOST_UPHILL_STRAIGHT,
- fixedBoost, 1f);
- //Debug.Log($"Adding Booster: {booster}");
- activeBooster.Add(booster);
- }
- public void SetFixedBoostForSlope(float slopeDegree)
- {
- var max = slopeDegree < 0 ? -maxSlopeDeg : maxSlopeDeg;
- fixedBoost = Mathf.Lerp(1f, slopeDegree < 0 ? MaxBoost : MinBoost, slopeDegree / max);
- }
- public void ResetFixedBoost()
- {
- fixedBoost = 1;
- }
- #region singleton
- private static readonly Lazy<BikeSpeedBooster>
- lazy =
- new Lazy<BikeSpeedBooster>
- (() => new BikeSpeedBooster());
- public static BikeSpeedBooster Instance => lazy.Value;
- private readonly List<Booster> activeBooster = new List<Booster>();
- #endregion
- }
- }
|