|
@@ -1,5 +1,6 @@
|
|
|
using System;
|
|
|
using UnityEngine;
|
|
|
+using Wheels;
|
|
|
|
|
|
namespace Controller.Bicycle
|
|
|
{
|
|
@@ -7,19 +8,22 @@ namespace Controller.Bicycle
|
|
|
{
|
|
|
#region Variables
|
|
|
|
|
|
- //private const float THRESHOLD_STANDING = 0.5f / 3.6f;
|
|
|
+ private const float THRESHOLD_GRADIENT_ZERO = .05f;
|
|
|
|
|
|
private Transform rbTransform;
|
|
|
private float currentSteerAngle;
|
|
|
private float currentLeaningAngle;
|
|
|
- private float currentSpeed;
|
|
|
+ private float currentSpeedSensed;
|
|
|
+ private float currentSpeedAdjusted;
|
|
|
+
|
|
|
+ [Header("Slope Impact")] public bool adjustSpeedToSlope = true;
|
|
|
|
|
|
public Vector3 Forward => rbTransform.forward;
|
|
|
|
|
|
public Vector3 Right => -rbTransform.right;
|
|
|
|
|
|
public Vector3 Up => rbTransform.up;
|
|
|
-
|
|
|
+
|
|
|
public BicycleControllerMode ControllerMode
|
|
|
{
|
|
|
get => controllerMode;
|
|
@@ -28,10 +32,12 @@ namespace Controller.Bicycle
|
|
|
|
|
|
public float CurrentSpeed
|
|
|
{
|
|
|
- get => currentSpeed;
|
|
|
- set => currentSpeed = Mathf.Clamp(value, 0, maxSpeed);
|
|
|
+ get => adjustSpeedToSlope ? currentSpeedAdjusted : currentSpeedSensed;
|
|
|
+ set => currentSpeedSensed = Mathf.Clamp(value, 0, maxSpeed);
|
|
|
}
|
|
|
|
|
|
+ public float CurrentSpeedKph => CurrentSpeed * 3.6f;
|
|
|
+
|
|
|
public float CurrentSteerAngle
|
|
|
{
|
|
|
get => currentSteerAngle;
|
|
@@ -70,13 +76,45 @@ namespace Controller.Bicycle
|
|
|
|
|
|
private void ApplyVelocity()
|
|
|
{
|
|
|
- var targetVelocity = new Vector3(0, 0, CurrentSpeed);
|
|
|
- targetVelocity = rbTransform.TransformDirection(targetVelocity);
|
|
|
+ var targetVelocity = CalculateTargetVelocity();
|
|
|
+
|
|
|
var velocityChange = targetVelocity - rigidBody.velocity;
|
|
|
velocityChange.y = 0;
|
|
|
rigidBody.AddForce(velocityChange, ForceMode.VelocityChange);
|
|
|
}
|
|
|
|
|
|
+ private Vector3 CalculateTargetVelocity()
|
|
|
+ {
|
|
|
+ AdjustSpeedToGradientIfNeeded();
|
|
|
+ var tv = new Vector3(0, 0, currentSpeedAdjusted);
|
|
|
+ tv = rbTransform.TransformDirection(tv);
|
|
|
+ return tv;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void AdjustSpeedToGradientIfNeeded()
|
|
|
+ {
|
|
|
+ var bikeAngle = rbTransform.localRotation.eulerAngles.x;
|
|
|
+ if (!adjustSpeedToSlope || Mathf.Abs(bikeAngle) <= THRESHOLD_GRADIENT_ZERO)
|
|
|
+ {
|
|
|
+ currentSpeedAdjusted = currentSpeedSensed;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (bikeAngle > 180)
|
|
|
+ {
|
|
|
+ bikeAngle -= 360f;
|
|
|
+ }
|
|
|
+ else if (bikeAngle < -180)
|
|
|
+ {
|
|
|
+ bikeAngle = 360f - bikeAngle;
|
|
|
+ }
|
|
|
+
|
|
|
+ var gradientDeg = -bikeAngle;
|
|
|
+ var gradient = Mathf.Tan(gradientDeg * Mathf.Deg2Rad);
|
|
|
+ currentSpeedAdjusted = gradient < 0 ? currentSpeedSensed * 1.5f :
|
|
|
+ BicyclePhysics.SpeedAtGradientForSpeedAtFlat(currentSpeedSensed, rigidBody.mass, gradient); //TODO make work for downhill - and lerp between the speeds!
|
|
|
+ }
|
|
|
+
|
|
|
private void ApplySteerAngleAndRotation()
|
|
|
{
|
|
|
//don't lean and rotate when veeeeeery sloooow/standing. Otherwise bike will rotate already
|