143 lines
3.8 KiB
C#
143 lines
3.8 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 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;
|
|
private PlayerInputHandler playerInput;
|
|
|
|
public bool IsBot = false;
|
|
// Update is called once per frame
|
|
|
|
private void Start()
|
|
{
|
|
playerInput = GetComponent<PlayerInputHandler>();
|
|
}
|
|
|
|
void Update()
|
|
{
|
|
if (_isCutsceneMovement)
|
|
return;
|
|
|
|
if (!IsBot && playerInput.Boost)
|
|
{
|
|
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;
|
|
}
|
|
|
|
private bool _isCutsceneMovement = false;
|
|
|
|
public void CutsceneMovement()
|
|
{
|
|
_isCutsceneMovement = true;
|
|
speed = cutsceneSpeed;
|
|
}
|
|
}
|