HOW TO CREATE A SIMPLE TRAFFIC CAR SYSTEM IN UNITY

Build an ambient road traffic system where autonomous AI cars follow waypoints, brake for obstacles using Raycasts, and pool efficiently for mobile 60 FPS.

Quick Architecture Overview

An efficient traffic car uses a lightweight script that navigates between an array of Transform waypoints with Vector3.MoveTowards() and Quaternion.RotateTowards(), while casting a forward Physics.Raycast() to automatically brake when approaching other cars or player vehicles.

1

The Traffic Car Controller C# Script

TrafficCarAI.cs (C#)
using System.Collections.Generic;
using UnityEngine;

public class TrafficCarAI : MonoBehaviour
{
    [Header("Speed & Navigation")]
    [SerializeField] private float topSpeed = 12f; // m/s
    [SerializeField] private float turnSpeed = 90f; // deg/s
    [SerializeField] private float reachThreshold = 1.5f;

    [Header("Obstacle Detection")]
    [SerializeField] private float sensorLength = 8f;
    [SerializeField] private LayerMask obstacleLayer;

    [Header("Waypoints")]
    [SerializeField] private List<Transform> waypoints = new List<Transform>();
    private int currentWaypointIndex = 0;

    private float currentSpeed;

    private void Start()
    {
        currentSpeed = topSpeed;
    }

    private void Update()
    {
        if (waypoints == null || waypoints.Count == 0) return;

        bool isBlocked = CheckForwardObstacle();
        
        // Smoothly accelerate or brake
        float targetSpeed = isBlocked ? 0f : topSpeed;
        currentSpeed = Mathf.MoveTowards(currentSpeed, targetSpeed, (isBlocked ? 25f : 8f) * Time.deltaTime);

        NavigateTowardsWaypoint();
    }

    private void NavigateTowardsWaypoint()
    {
        Transform targetNode = waypoints[currentWaypointIndex];
        Vector3 targetPosition = new Vector3(targetNode.position.x, transform.position.y, targetNode.position.z);
        Vector3 direction = (targetPosition - transform.position).normalized;

        if (direction != Vector3.zero)
        {
            // Rotate smoothly towards waypoint
            Quaternion targetRotation = Quaternion.LookRotation(direction);
            transform.rotation = Quaternion.RotateTowards(transform.rotation, targetRotation, turnSpeed * Time.deltaTime);
        }

        // Move forward
        transform.position += transform.forward * (currentSpeed * Time.deltaTime);

        // Check if reached current waypoint
        if (Vector3.Distance(transform.position, targetPosition) < reachThreshold)
        {
            currentWaypointIndex = (currentWaypointIndex + 1) % waypoints.Count;
        }
    }

    private bool CheckForwardObstacle()
    {
        Vector3 rayOrigin = transform.position + Vector3.up * 0.5f;
        return Physics.Raycast(rayOrigin, transform.forward, sensorLength, obstacleLayer);
    }

    public void SetPath(List<Transform> pathNodes)
    {
        waypoints = pathNodes;
        currentWaypointIndex = 0;
    }
}
Mobile Optimization Pro Tip:
Never instantiate and destroy traffic cars dynamically during gameplay. Use an Object Pool to recycle inactive cars when they move beyond the camera view frustum.

Related Vehicle Tutorials