Traffic Car

How To Create

  1. Create a vehicle using the Car Prefab Creator tool (for example Simple physics entity type, if you need traffic with controller based on MonoBehaviour, read this article).

    _images/Step1.png

    Car Prefab Creator final step example.

  2. Make sure, that the vehicle collection contains vehicle you have created.

    _images/Step2.png
  3. Make sure, that the preset contains the vehicle.

    _images/Step3.png
  4. Open the Traffic settings and select the Simple physics entity type (if you have created a Simple physics entity).

    _images/Step4.png
  5. Open the Hub object in the scene and press the Copy To Subscene button.

    _images/Step5.png
  6. Open the EntitySubScene, find the TrafficCarEntityPoolBakerRef gameobject on the main & subscene, make sure the correct preset is assigned to both scenes.

    _images/Step6.png
  7. Adjust the traffic settings of the created vehicles.

Vehicle Physics Types

Custom Physics

Authoring components

Vehicle Authoring
_images/vehicleAuthoring.png
Wheel
_images/wheel.png
Wheel mass : wheel mass.
Max steering angle : max steering angle of the steering wheel in degrees.
Power steering : rate of steering improvement.
Custom steering limit : limiting steering angle based on vehicle speed (Y-axis rate value (1 - max steering angle), X-axis speed in metres per second).
Radius : wheel radius.
Width : wheel width.
Apply impulse offset : applying force offset relative to lower point of wheel (without offsetting the force applied to the lower point of the wheel).
Cast type:
  • Ray : raycast by ray.

  • Collider : raycast by collider (collider size based on wheel radius and width).

Cast layer : physical layer that collides with the wheel.
Suspension
_images/suspension.png
Suspension length : length of suspension.
Stiffness : spring stiffness of suspension.
Damping : force to return spring to its original length.
Friction
_images/friction1.png
Longitudinal : forward friction curve (Y-axis - forward slip value, X-axis forward speed in metres per second).
Lateral : lateral friction curve (Y-axis - lateral slip value, X-axis lateral speed in metres per second).
Forward friction : forward friction value.
Lateral friction : lateral friction value.
Brake friction : brake friction value.
Drag : drag value of the vehicle.
Transient Forces
_images/transientForce.png

Transient force is required to hold the car on an inclined ramp during manual braking.

Use forward transient force : on/off forward transient force.
Min transient forward speed : min forward speed when transient force is applied.
Max forward friction rate : max friction for transient force calculated by multiplying the entered rate by the forward friction.
Forward relax multiplier : step of forward force increase per frame.
Use lateral transient force : on/off lateral transient force.
Min transient lateral speed : min lateral speed when transient force is applied.
Max lateral friction rate : max friction for transient force calculated by multiplying the entered rate by the lateral friction.
Lateral relax multiplier : step of lateral force increase per frame.
Brakes
_images/brakes.png
Brake torque : torque of brake.
Handbrake torque : torque of handbrake.
Engine
_images/engine1.png
Torque : engine torque.
Transimission rate : engine torque to wheel speed ratio.
Scene Settings
_images/sceneSettings.png
Show debug : on/off debugging for wheel and suspension at runtime (VehicleCustomDebugger).
Show suspension origin : on/off display of suspension origin.
Show suspension : on/off display of suspension.
Origin move:
  • Disabled : disabled handle.

  • Wheel : on/off handle for wheel origin.

  • Suspension origin : on/off handle for suspension origin.

  • Suspension : on/off handle for suspension and wheel origin.

Template Settings
_images/templateSettings.png
Tabs:
  • Create new : create a new template settings.

  • Copy from template : copy settings from the selected template.

  • Save to template : save settings to the selected template.

Copy settings type:
  • Physics settings : copy the physics settings (mass, damping, gravity) of the PhysicsBody component.

  • Center of mass : copy the center of mass local position of the PhysicsBody component.

  • Offsets : copy the local offset of the wheels.

  • Settings : copy the settings of the VehicleAuthoring component.

Wheel Refs
_images/wheelRefs.png
Wheel : reference to wheel.
Driving : on/off driving force for the wheel.
Brake : on/off braking force for the wheel.
Brake rate : brake rate.
Handbrake rate : handbrake rate.
PhysicsBody
_images/physicsBody.png
PhysicsShape
_images/physicsShape.png

Example

Simple Physics

Authoring components

CarWheelAuthoring
_images/CarWheelAuthoring.png
Wheel base : wheel radius.
All wheels : all wheels of the vehicle.
Steering wheels : wheels that can turn.
PhysicsBody
_images/PhysicsBody.png
PhysicsShape
_images/physicsShape1.png

Example

Optional components if the car moves with physics.

No Physics

Hybrid Mono

Arcade (built-in sample)

If you want to use Arcade’s built-in sample controller, follow these steps:

  1. Open the Car Prefab Creator tool.

  2. Select Prefab tab.

  3. Set Car type to Traffic.

  4. Drag & drop your prefabs into the prefabs field (make sure your source Prefabs don’t have any Colliders, Wheel colliders & Rigidbodies).

  5. Press Scan button.

  6. Select Save tab.

  7. Set Entity type to Hybrid entity mono physics.

  8. Set Controller type to Arcade.

  9. Set desired preset. Also hull & save paths.

  10. Select Prefab info tab.

  11. Customize hull & wheel offsets.

  12. Customize traffic related settings.

  13. Press Create button.

  14. In the ArcadeVehicleController, make sure the raycast layer matches your Ground layer.

  15. Open the EntitySubScene, find the TrafficCarEntityPoolBakerRef gameobject on the main & subscene, make sure the correct preset is assigned to both scenes.

    _images/Step6.png

Custom user controller

If you want to use your own custom solution, follow these steps:

  1. Open the Car Prefab Creator tool.

  2. Select Prefab tab.

  3. Set Car type to Traffic.

  4. Drag & drop your prefabs into the prefabs field.

  5. Press Scan button.

  6. Select Save tab.

  7. Set Entity type to Hybrid entity mono physics.

  8. Set Controller type to Custom user.

  9. Create script that implements IVehicleInput interface to link traffic input & your vehicle controller input (code example below)

  10. Assign created script into the Input script field.

  11. Set desired preset. Also hull & save paths.

  12. Select Prefab info tab.

  13. Set the steering angle to match the steering of your custom car controller.

  14. Customize traffic related settings.

  15. Press Create button.

  16. To set your own custom Car Controller parameters to handle the most common traffic situations, use the Traffic test scene.

  17. Open the EntitySubScene, find the TrafficCarEntityPoolBakerRef gameobject on the main & subscene, make sure the correct preset is assigned to both scenes.

    _images/Step6.png

Input info

  • Throttle [1] : forward motion.

  • Throttle [-1] : reverse motion.

  • Throttle [0] : hand brake.

  • Throttle [-0.9] : braking, for example, if the current speed is higher than permitted. (the value can be changed in the Traffic settings)

  • Steering [-1, 1]

VehicleInput example code

public class UVC_adapter : MonoBehaviour, IVehicleInput
{
        // Replace by your custom controller script.
        // The example uses a "Universal Vehicle Controller".
        // https://assetstore.unity.com/packages/tools/physics/universal-vehicle-controller-plus-176314
        public UVC_AIControl carControllerInput;

        public float Throttle
        {
                get => carControllerInput.Acceleration;
                set
                {
                        if (value > 0)
                        {
                                carControllerInput.SetAcceleration(value);
                                carControllerInput.SetBrakeReverse(0);
                                carControllerInput.SetHandBrake(false);
                        }
                        else
                        {
                                carControllerInput.SetAcceleration(0);
                                carControllerInput.SetBrakeReverse(Mathf.Abs(value));

                                if (value == 0)
                                        carControllerInput.SetHandBrake(true);
                        }
                }
        }

        public float Steering { get => carControllerInput.Horizontal; set => carControllerInput.SetSteer(value); }
        public bool Handbrake { get => carControllerInput.HandBrake; set => carControllerInput.SetHandBrake(value); }

        public void SwitchEnabledState(bool isEnabled)
        {
                carControllerInput.enabled = isEnabled;
        }
}

Car Player Blocker

The CarPlayerBlocker component is designed specifically for Hybrid Mono vehicles. It prevents a custom player physics controller from pushing or moving AI traffic vehicles upon collision.

It achieves this by dynamically creating an independent kinematic collider on a dedicated physics layer. This layer forces the player’s controller to recognize the traffic car as an immovable obstacle, while the traffic car itself ignores this internal blocker collider to prevent self-jittering.

Note

This component works only for vehicles with the Hybrid entity mono physics type. It does not affect Pure DOTS entities.

How It Works
  1. Editor Generation: The editor script copies the dimensions and center boundaries of your vehicle’s main source collider (supports BoxCollider or MeshCollider).

  2. Layer Isolation: It places this newly generated box collider onto a custom physics layer (e.g., PlayerBlocker).

  3. Kinematic Rigidbody: A kinematic Rigidbody is automatically attached to the blocker object, making it completely unyielding to the player’s physical forces.

  4. Collision Filtering: At runtime (in Awake), the script automatically configures Unity’s physics engine to ignore collisions between the vehicle’s driving colliders and this blocker collider.

Inspector Parameters
Source Collider : The main physical collider of the traffic vehicle.
Player Blocker Layer : The physics layer intended to collide exclusively with your Player Controller.
Size Offset : Additional padding added to the blocker collider dimensions to detect or block the player slightly outside the mesh bounds.
Physics Switcher : Reference to the PhysicsSwitcher component to properly reset and synchronize collider states during culling.
Created Collider : The automatically generated BoxCollider slot.
Step-by-Step Configuration

Follow these steps to set up the blocker for your vehicles:

  1. Create a New Layer: Open your Unity project settings and add a new layer (e.g., name it PlayerBlocker).

  2. Attach the Component: Add the CarPlayerBlocker component to your vehicle’s hull prefab.

  3. Configure the Blocker:
    • Assign the Source Collider and the Physics Switcher.

    • Set the Player Blocker Layer to the layer you created in Step 1.

    • Click the Create button in the inspector. This will spawn a child GameObject named PlayerBlocker with a box collider and a kinematic rigidbody.

  4. Configure the Layer Collision Matrix:
    • Navigate to Project Settings -> Physics.

    • Locate the Layer Collision Matrix grid.

    • For the PlayerBlocker layer, untick all checkboxes except for the layer used by your Player character/vehicle controller.

Note

This matrix setup ensures the blocker collider interacts only with the player and remains completely invisible to traffic, NPCs, raycasts, and ground physics layers.

Components

CarEntityAdapter

_images/CarEntityAdapter.png

Component to syncronize gameobject & entity, also to switch physics & scripts of the vehicle when cull state changes with PhysicsSwitcher & ScriptSwitcher components.

Note

You can turn off traffic physics culling in the Traffic settings.

PhysicsSwitcher

_images/PhysicsSwitcher.png

Component to on/off physics of the vehicle.

ScriptSwitcher

_images/ScriptSwitcher.png

Component to on/off scripts of the vehicle.

Common Authoring Components

TrafficCarEntityAuthoring

_images/TrafficCarEntityAuthoring.png

Main component of traffic entity [required].

Hull mesh renderer : vehicle hull mesh renderer reference.
Physics shape : vehicle entity PhysicsShape reference.
Faction type : selected faction type of vehicle.
Car type : selected car type of vehicle.
Bounds source type : selected bounds source for the entity bounds.
Traffic group : selected traffic group.

Shared Settings

Each vehicle has a common set of settings that are described here

CarSoundAuthoring

_images/CarSoundAuthoring.png

Component for vehicle sounds [optional].

HealthAuthoring

Vehicle health component for damage system (DOTS only) [optional].

CarDamageEngineAuthoring

Component for visual presentation of damage in the damage systems (DOTS only) [optional].

PlayerTargetAuthoring

Component for player targeting systems [optional].

CullState Info

States

Avoidance

Avoidance is used in the case of stuck vehicles.
Currently enabled in the following situations:
_images/AvoidanceExample1.png

Cyclical obstacle example.

_images/AvoidanceExample2.png

Avoiding cyclical obstacle example.

Note

Test scene example.

Entity Selection

Entity can be retrieved using one of these methods:

Pure DOTS

  • Create a new gameobject with EntitySelectionService component

  • Use world position to get the nearest entity for that position.

    public Entity TryToSelectEntity(Vector3 worldPosition)
    {
            return EntitySelectionService.Instance.SelectEntity(worldPosition, EntityType.Traffic, 1f);
    }
    

Hybrid Mono

Entity can be retrieved if the car has a collider:

private Entity GetEntity()
{
        Entity entity = Entity.Null;

    if (Physics.Raycast(transform.position, Vector3.forward, out hit, 1.0f))
        {
                var hybridEntityRef = hit.collider.GetComponent<IHybridEntityRef>();
                entity = hybridEntityRef.RelatedEntity;
        }

        return entity;
}

Rail Movement

The Rail movement is used to drive the vehicle precisely along the path, which can be useful in small enclosed parking areas, for example. To enable rail movement, tick on the Rail parameter in the path settings. Open the rail config to adjust the Rail parameters (DOTS only).

Note

Enabled by default for trams.

Obstacle Detection

Raycast

Config

TrafficCarRaycastConfig.

Debugger

TrafficCarRaycastDebugger.

Modes

  • Hybrid mode : raycast is activated only when the selected targets are close to the car.

  • Raycast only : raycasts are sent constantly.

To define raycast targets for Hybrid or Raycast only modes, redefine the GetTargetQuery method in the TrafficCarRaycastObstacleTargetQueryProvider class, which returns the EntityQuery of the targets.

public static EntityQuery GetTargetQuery(
                   SystemBase sourceSystem,
                   TrafficCarDetectObstacleMode trafficCarDetectObstacleMode,
                   TrafficCarDetectNpcMode trafficCarDetectNpcMode,
                   out CollisionFilter tempRaycastCollisionFilter,
                   out CollisionFilter raycastAlwaysCollisionFilter);

Obstacle Avoidance

If you want the traffic to avoid obstacles, follow these steps:

  • Make sure that obstacle detection is set to either Hybrid or Raycast in the Traffic config.

  • Ensure that Advanced avoidance is enabled in the Collision config.

  • Make sure that the traffic Raycast config includes an obstacle layer.

  • Add components to the obstacle object from the example below, depending on the type of obstacle.

Player Character

_images/PlayerCharacterAvoidance.png

Note

Make sure that Player Npc Hybrid Component is removed.

Player Car

_images/PlayerCarAvoidance.png

Dynamic Obstacle

_images/CustomObstacleAvoidance.png

Static Obstacle

_images/CustomStaticObstacleAvoidance.png

Left-hand Drive

To make the traffic left-hand drive:

  • Find & open ProjectConstants script.

  • Change the LaneHandDirection variable to -1.

    Note

    Changing this parameter will only affect newly created scenes. Old scenes with a different lane direction will not work.

Pathfinding

Custom Point

To set a custom destination for a specific traffic car, do the following:

  • Create a new gameobject with EntitySelectionService component.

  • Create a new gameobject with TrafficCustomPathService component.

  • Use this sample code:

    private void Awake()
    {
            PathHashMapSystem.Register();
    }
    
    public void SetEntity(Vector3 trafficPosition, Vector3 destination)
    {
            var trafficEntity = EntitySelectionService.Instance.SelectEntity(trafficPosition, EntitySelectionService.EntityType.Traffic, 2f);
            TrafficCustomPathService.Instance.SetFollowPath(trafficEntity, destination);
    }
    
  • Use the OnStatusUpdated callback in TrafficCustomPathService to listen to the current state of the traffic car’s pathfinding.

Custom Node

To set a custom node destination for a specific traffic car, do the following:

  • Create a new gameobject with EntitySelectionService component.

  • Create a new gameobject with TrafficCustomPathService component.

  • Use this sample code:

    private void Awake()
    {
            PathHashMapSystem.Register();
    }
    
    public void SetEntity(Vector3 trafficPosition, Vector3 destination)
    {
            var trafficEntity = EntitySelectionService.Instance.SelectEntity(trafficPosition, EntitySelectionService.EntityType.Traffic, 2f);
            var destinationPath = PathHashMapSystem.GetClosestPath(destination);
    
            TrafficCustomPathService.Instance.SetFollowPath(trafficEntity, destinationPath);
    }
    
  • Use the OnStatusUpdated callback in TrafficCustomPathService to listen to the current state of the traffic car’s pathfinding.

  • As an alternative, you can check the TrafficPathSelector prefab for an interactive user-selected path used in the RuntimeTileRoad Demo scene (runtime sample should be imported & RUNTIME_ROAD scripting define added).