142 lines
4.6 KiB
C#
142 lines
4.6 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using Unity.XR.CoreUtils;
|
|
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)
|
|
{
|
|
if (other.GetComponent<XROrigin>() == null) return;
|
|
StartCoroutine(SmoothAdjustSpeed(0, 0, haltspeed)); // Smoothly halt in 1 second
|
|
_tireSound.Stop();
|
|
_stopSound.Play();
|
|
}
|
|
|
|
private void OnTriggerExit(Collider other)
|
|
{
|
|
if (other.GetComponent<XROrigin>() == null) return;
|
|
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;
|
|
}
|
|
}
|