rabidus-test/Assets/Scripts/ShipPathFollower.cs

142 lines
4.0 KiB
C#

using Dreamteck.Splines;
using PathCreation;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.InputSystem;
public class ShipPathFollower : MonoBehaviour, ITextChangable
{
public float speed = 10f;
public float minSpeed = 1f;
public float maxSpeed = 20f;
public float frictionForce = 0.1f;
public float gravityForce = 1f;
public float slopeRange = 60f;
public float cutsceneSpeed = 50f;
[SerializeField]
private SplineFollower follower;
public AnimationCurve speedGain;
public AnimationCurve speedLoss;
public float brakeSpeed = 0f;
public float brakeReleaseSpeed = 0f;
private float brakeTime = 0f;
private float brakeForce = 0f;
private float addForce = 0f;
public float soundFadeLength = 0.15f;
public InputActionReference LeftTrigger;
public InputActionReference RightTrigger;
public UnityEvent<object> OnTextChange => _OnTextChange;
private UnityEvent<object> _OnTextChange = new UnityEvent<object>();
public UnityEvent<float> OnSpeedChange;
public UnityEvent<float> OnSpeedPercentChange;
public UnityEvent<float> OnBoostPercentChange;
public float SpeedPercent;
private float _boostSpeed;
[SerializeField] private float _boostBreakSpeed;
public bool IsBot = false;
// Update is called once per frame
void Update()
{
if (_isCutsceneMovement)
return;
if (!IsBot && (Input.GetKey(KeyCode.W) || RightTrigger.action.inProgress && LeftTrigger.action.inProgress))
{
AddForce(1);
}
float dot = Vector3.Dot(this.transform.forward, Vector3.down);
float dotPercent = Mathf.Lerp(-slopeRange / 90f, slopeRange / 90f, (dot + 1f) / 2f);
speed -= Time.deltaTime * frictionForce * (1f - brakeForce);
float speedAdd = 0f;
float speedPercent = Mathf.InverseLerp(minSpeed, maxSpeed, speed);
if (dotPercent > 0f)
{
speedAdd = gravityForce * dotPercent * speedGain.Evaluate(speedPercent) * Time.deltaTime;
}
else
{
speedAdd = gravityForce * dotPercent * speedLoss.Evaluate(1f - speedPercent) * Time.deltaTime;
}
speed += speedAdd * (1f - brakeForce);
_boostSpeed -= Time.deltaTime * _boostBreakSpeed;
_boostSpeed = Mathf.Clamp(_boostSpeed, 0, float.MaxValue);
speed = Mathf.Clamp(speed, minSpeed, maxSpeed + _boostSpeed);
if (addForce > 0f)
{
float lastAdd = addForce;
addForce = Mathf.MoveTowards(addForce, 0f, Time.deltaTime * 30f);
speed += lastAdd - addForce;
}
follower.followSpeed = speed;
follower.followSpeed *= (1f - brakeForce);
if (brakeTime > Time.time)
brakeForce = Mathf.MoveTowards(brakeForce, 1f, Time.deltaTime * brakeSpeed);
else
brakeForce = Mathf.MoveTowards(brakeForce, 0f, Time.deltaTime * brakeReleaseSpeed);
SpeedPercent = Mathf.Clamp01(speed / maxSpeed) * (1f - brakeForce);
_OnTextChange?.Invoke((int)speed);
OnSpeedChange?.Invoke(speed);
OnSpeedPercentChange?.Invoke(SpeedPercent);
}
public void AddBrake(float time)
{
brakeTime = Time.time + time;
}
public void FastBreak(float multiplier)
{
speed *= multiplier;
}
public void FastBoost(float value)
{
_boostSpeed = value;
speed += _boostSpeed;
}
public void RemoveBrake()
{
brakeTime = 0f;
}
public void ChangeMaxSpeed(float newSpeed)
{
maxSpeed = newSpeed;
}
public void AddForce(float amount)
{
addForce = amount;
if (!IsBot)
addForce *= RightTrigger.action.ReadValue<float>() * LeftTrigger.action.ReadValue<float>();
}
private bool _isCutsceneMovement = false;
public void CutsceneMovement()
{
_isCutsceneMovement = true;
speed = cutsceneSpeed;
}
}