Hello,
I was going through the Delivery Driver section for a second time, and I wanted to try and make it more interesting. I thought “I could add cars as obstacles on the road, but moving by themselves.” I added waypoints and got help implementing the code for that…my question is how can I make the vehicles behave more like real cars? They float around like hovercraft. It still makes for good obstacles, but it would be better if they steered. Here is my code for car movement, I would appreciate any suggestions to implement steering in the non-player controlled cars.
‘’’ using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CarMovement : MonoBehaviour
{
[SerializeField] private float moveSpeed = 5f;
[SerializeField] private float arrivalThreshold = 0.1f;
[SerializeField] private Transform waypointsContainer;
private Transform[] waypoints;
private int currentWaypointIndex = 0;
private Rigidbody2D rb;
public Transform[] wheelVisuals;
public WheelCollider[] wheelColliders;
void Start()
{
waypoints = new Transform[waypointsContainer.childCount];
for (int i = 0; i < waypointsContainer.childCount; i++)
{
waypoints[i] = waypointsContainer.GetChild(i);
}
// Initialize the Rigidbody
rb = GetComponent<Rigidbody2D>();
rb.gravityScale = 0f; // Disable gravity for the car
// Check if the arrays have the same length
if (wheelVisuals.Length != wheelColliders.Length)
{
Debug.LogError("The number of wheel visual transforms doesn't match the number of wheel colliders.");
return;
}
// Assign visual wheel transforms to the Wheel Colliders
for (int i = 0; i < wheelColliders.Length; i++)
{
WheelCollider wheelCollider = wheelColliders[i];
Transform wheelVisual = wheelVisuals[i];
// Check if both the Wheel Collider and visual transform are assigned
if (wheelCollider != null && wheelVisual != null)
{
wheelCollider.center = wheelVisual.localPosition;
}
else
{
Debug.LogError("One or more wheel colliders or visual transforms are not assigned.");
}
}
}
void Update()
{
MoveToNextWaypoint();
// Calculate the direction to the next waypoint
Vector3 directionToWaypoint = waypoints[currentWaypointIndex].position - transform.position;
// Calculate the desired steering angle based on the direction
float desiredSteeringAngle = Vector3.SignedAngle(transform.forward, directionToWaypoint, transform.up);
// Apply the desired steering angle to the front wheel colliders
wheelColliders[0].steerAngle = desiredSteeringAngle;
wheelColliders[1].steerAngle = desiredSteeringAngle;
// Gradually adjust the steering angle
float steeringSpeed = 5f; // Adjust as needed
float currentSteeringAngle = wheelColliders[0].steerAngle;
wheelColliders[0].steerAngle = Mathf.Lerp(currentSteeringAngle, desiredSteeringAngle, Time.deltaTime * steeringSpeed);
wheelColliders[1].steerAngle = Mathf.Lerp(currentSteeringAngle, desiredSteeringAngle, Time.deltaTime * steeringSpeed);
if (wheelColliders.Length > 0)
{
// Access the first element in the wheelColliders array
wheelColliders[0].steerAngle = desiredSteeringAngle;
}
if (waypoints.Length > 0 && currentWaypointIndex < waypoints.Length)
{
// Access the waypoint at the current index
Vector3 targetDirection = waypoints[currentWaypointIndex].position - transform.position;
// Calculate desired steering angle based on directionToWaypoint
// ...
}
}
void MoveToNextWaypoint()
{
// Check if the car reached the current waypoint
if (Vector2.Distance(transform.position, waypoints[currentWaypointIndex].position) <= arrivalThreshold)
{
currentWaypointIndex++;
// Loop back to the first waypoint if all waypoints have been visited
if (currentWaypointIndex >= waypoints.Length)
{
currentWaypointIndex = 0;
}
}
// Calculate the direction to the current waypoint
Vector2 direction = (waypoints[currentWaypointIndex].position - transform.position).normalized;
// Apply a force to move the car towards the waypoint
rb.velocity = direction * moveSpeed;
}
}
‘’’