2024-12-28 18:15:03 +02:00

139 lines
4.4 KiB
C#

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using static MouseLook;
public class CarDrivingRoutine : MonoBehaviour
{
public AudioSource _stopSound;
public AudioSource _tireSound;
public Waypoint _waypoint;
public float StraightSpeed = 5f; // Movement speed
public float rotationSpeed = 5f; // Rotation speed
public float waypointProximityThreshold = 0.5f; // Distance to consider "close enough" to a waypoint
private bool isTurning = false;
private float tireTurnAngle = -40;
private float haltspeed = 1f;
private float targetSpeed;
private float targetRotationSpeed;
[Header("Tires")]
public List<GameObject> FrontTires;
public List<GameObject> BackTires;
private void Start()
{
targetSpeed = StraightSpeed;
targetRotationSpeed = rotationSpeed;
}
// Update is called once per frame
void Update()
{
//if (hasPedestrianInFront) return;
if (_waypoint == null) return; // Just in case.
// Move towards the waypoint
Vector3 targetPosition = _waypoint.transform.position;
float step = StraightSpeed * Time.deltaTime;
transform.position = Vector3.MoveTowards(transform.position, targetPosition, step);
// Rotate towards the desired rotation
float targetRotation = _waypoint.DesiredRotation;
Quaternion desiredRotation = Quaternion.Euler(0, targetRotation, 0);
transform.rotation = Quaternion.RotateTowards(transform.rotation, desiredRotation, rotationSpeed * Time.deltaTime);
rollTires(); // Just an aesthetic improvement.
if (Quaternion.Angle(transform.rotation, desiredRotation) > 1f) // If the car is turning.
{
if (!isTurning)
{
setTireRotation(tireTurnAngle);
}
isTurning = true;
}
if (Quaternion.Angle(transform.rotation, desiredRotation) <= 1f) // Reset the turn value.
{
if (isTurning)
{
setTireRotation(-tireTurnAngle);
}
isTurning = false;
}
// Check if close enough to the waypoint
if (Vector3.Distance(transform.position, targetPosition) <= waypointProximityThreshold &&
Quaternion.Angle(transform.rotation, desiredRotation) <= 1f)
{
// Proceed to the next waypoint
_waypoint = _waypoint.Next;
}
}
private void rollTires()
{
float tireRollModifier = -9 * rotationSpeed; // Multiplies the value so, that the roll looks natural.
foreach (GameObject tire in FrontTires)
{
tire.transform.Rotate(tireRollModifier * Time.deltaTime, 0, 0);
}
foreach (GameObject tire in BackTires)
{
tire.transform.Rotate(tireRollModifier * Time.deltaTime, 0, 0);
}
}
private void setTireRotation(float rotation)
{
foreach (GameObject tire in FrontTires)
{
Vector3 currentRotation = tire.transform.eulerAngles;
currentRotation.y += rotation;
tire.transform.eulerAngles = currentRotation;
}
}
private void OnTriggerEnter(Collider other)
{
StartCoroutine(SmoothAdjustSpeed(0, 0, haltspeed)); // Smoothly halt in 1 second
_tireSound.Stop();
_stopSound.Play();
}
private void OnTriggerExit(Collider other)
{
StartCoroutine(SmoothAdjustSpeed(targetSpeed, targetRotationSpeed, haltspeed)); // Smoothly resume speed in 1 second
_stopSound.Stop();
_tireSound.Play();
}
private IEnumerator SmoothAdjustSpeed(float targetStraightSpeed, float targetRotationSpeed, float duration)
{
float initialStraightSpeed = StraightSpeed;
float initialRotationSpeed = rotationSpeed;
float elapsedTime = 0f;
while (elapsedTime < duration)
{
elapsedTime += Time.deltaTime;
float t = elapsedTime / duration;
// Smooth interpolation (you can use Mathf.Lerp or Mathf.SmoothStep)
StraightSpeed = Mathf.Lerp(initialStraightSpeed, targetStraightSpeed, t);
rotationSpeed = Mathf.Lerp(initialRotationSpeed, targetRotationSpeed, t);
yield return null; // Wait for the next frame
}
// Ensure final values are set
StraightSpeed = targetStraightSpeed;
rotationSpeed = targetRotationSpeed;
}
}