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 FrontTires; public List 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() == null) return; StartCoroutine(SmoothAdjustSpeed(0, 0, haltspeed)); // Smoothly halt in 1 second _tireSound.Stop(); _stopSound.Play(); } private void OnTriggerExit(Collider other) { if (other.GetComponent() == 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; } }