Lights System

This document covers RCC's lighting system: how to add headlights, brake lights, reverse lights, indicators, and interior lights to a vehicle, how lights respond to driver inputs, how to configure lens flares, and how the system handles differences between Built-in / URP / HDRP.

How RCC Lights Work

Every RCC light is a child GameObject under the vehicle with two components:

  1. Unity's Light component — the actual light source.
  2. RCC's RCC_Light component — wraps the Unity Light with logic that knows when to turn it on, dim it, blink it, or break it.

Each frame, RCC_Light reads the parent vehicle's state — is the brake pressed, is reverse engaged, is the left indicator on — and sets the Unity Light's intensity accordingly.

For example, a brake light's intensity goes to 0 when the driver isn't braking, and ramps up to its configured max when the driver is. The transition is smooth, not instant, which makes the lighting feel like real brake lights instead of a digital on/off.

Light Types

RCC_Light has an enum field lightType with these options:

Type Behavior
Headlight Low Beam On when low-beam input is toggled.
Headlight High Beam On when high-beam input is toggled.
Brake Light Bright when brakeInput > 0. Dim when on but not braking (parking light behavior — optional).
Reverse Light On when the vehicle is in reverse gear (direction == -1).
Indicator Left Blinks at a fixed interval when the left indicator is on.
Indicator Right Same for right.
Indicator Hazard Hazard mode — both left and right blink together.
Interior Light On when the interior light toggle is on.
Tail Light Always-on glow when headlights are on (lower than brake light intensity).

Adding Lights to a Vehicle

The recommended workflow uses the menu items, which handle all the wiring automatically.

Adding a Headlight

  1. Create an empty GameObject at the headlight position on the front of the vehicle.
  2. Select it.
  3. Menu: Tools → BoneCracker Games → Realistic Car Controller → Create → Lights → Add Lights To Vehicle → HeadLight.

The menu does the following:

Repeat for the right headlight on the front-right side of the vehicle.

Adding a Brake Light

Same pattern but the menu is Lights → Brake. Place at the rear of the vehicle.

The default brake light is configured to:

Adding a Reverse Light

Menu: Lights → Reverse. Place at the back, separate from the brake lights.

Adding Indicator Lights

Menu: Lights → Indicator → Left (for the left indicator) and Lights → Indicator → Right.

Each indicator GameObject gets a RCC_Light configured to blink. The blink rate is roughly 0.5 seconds on / 0.5 seconds off (matches real-world turn signal frequency).

Place left-indicator lights at the front left and rear left. Place right-indicator lights at the front right and rear right. The system handles all of them together — toggling left indicator on lights up both left lights.

Adding Interior Lights

Menu: Lights → Interior. Place inside the cabin (e.g., dome light). On by default when interior light input is toggled.

Customizing Light Properties

After you add a light, you'll likely want to tune it. Click the light GameObject and look at the Inspector.

Unity Light Component

Standard Unity settings:

RCC_Light Component

Multiple Lights as One Bulb

If you have a single "light fixture" mesh (e.g., a headlight assembly with one diffuser cover), you can use one RCC_Light GameObject and have it drive the emission on the diffuser material. The Light component lights the scene; the emission material makes the bulb itself glow.

To set up:

  1. The diffuser mesh's material has an emission slot (URP/Lit, HDRP/Lit, or Built-in/Standard all support this).
  2. On the RCC_Light component, enable Use Emission.
  3. Assign the diffuser material to Emission Material.
  4. Set the emission color to match the bulb (yellow-white for headlights).

When the light's intensity ramps up, the emission color ramps up too — the bulb glows.

Lens Flares

RCC ships with lens flare prefabs that work across all three render pipelines:

When the Render Pipeline Converter runs, it swaps the lens flare components on every RCC light automatically. You don't need to manage this by hand.

Disabling Lens Flares

Lens flares are aesthetic but can be distracting (especially with multiple cars in a scene at night). To disable globally:

  1. In RCC_Settings.asset, find each "Lights as vertex lights" toggle and decide if you want pixel or vertex lighting.
  2. Per-vehicle, uncheck Use Lens Flare on each RCC_Light.

For mobile or VR, lens flares are typically disabled for performance.

Light Performance — Vertex vs Pixel Lighting

A "real-time pixel light" is computed per pixel and looks great but is expensive. A "vertex light" is computed per vertex and is much cheaper but less crisp.

RCC_Settings has toggles for each light type:

If you're targeting mobile and seeing frame drops at night when many vehicles are visible, turn more of these to vertex.

Light Damage Integration

The damage system can break individual lights. See 12 — Damage System for the full picture. In short: enable Use Light Damage on the vehicle's RCC_Damage section, and lights will stop emitting after enough impacts in their vicinity.

When a light is broken, it stops contributing to the scene. Repair via RCC.Repair(carController) restores it.

Light Events

You can subscribe to indicator and headlight events through RCC_Events:

using UnityEngine;

public class IndicatorSound : MonoBehaviour {
    public AudioSource clickSound;

    void OnEnable() {
        RCC_Events.OnIndicatorLeft += PlayClick;
        RCC_Events.OnIndicatorRight += PlayClick;
    }

    void OnDisable() {
        RCC_Events.OnIndicatorLeft -= PlayClick;
        RCC_Events.OnIndicatorRight -= PlayClick;
    }

    void PlayClick() {
        clickSound.Play();
    }
}

The events fire when the input toggles, regardless of whether the indicator was on or off. To check current state, query the vehicle directly:

if (vehicle.indicatorsOn == RCC_CarControllerV4.IndicatorsOn.Left) { ... }

(Field name may vary slightly — check RCC_CarControllerV4.cs for the exact API in your version.)

Render Pipeline Considerations

Built-in Render Pipeline

URP (Universal Render Pipeline)

HDRP (High Definition Render Pipeline)

When you run the Render Pipeline Converter, RCC adjusts intensities for you. If you set up custom lights yourself, you may need to manually re-tune intensity per pipeline.

Tuning Light Intensity for Realism

A good rule of thumb:

These are starting points — adjust based on your scene's ambient lighting.

Common Light Issues

"Headlights don't turn on"

Check that you've added the right lightType to the RCC_Light component. A light with lightType = BrakeLight won't turn on when you press the headlight key.

Also verify your scene has an RCC_InputManager and that the headlight input is bound in the Input Actions asset.

"Lights look blown out at night"

Lower the intensity. Try halving it. HDRP especially is sensitive to high lumen counts.

"Lights don't cast light on the scene, just glow on themselves"

The Unity Light component might be disabled, or its Range is too short. Increase Range to ~30 meters for headlights, ~5 meters for brake lights.

The RCC_Light component might be set to the wrong lightType. Indicator lights need IndicatorLeft or IndicatorRight, not BrakeLight.

"Lens flare appears even during the day"

Lens flares always render. To make them appear only at night, write a script that toggles useLensFlare on every RCC_Light based on your day/night system.

Adding a Custom Light Type

If RCC's built-in light types don't cover your use case (e.g., a custom "police siren" flashing red/blue, or a "warning beacon"), you have two options:

  1. Use RCC_PoliceSiren — included specifically for police-style lights. See Scripts/RCC_PoliceSiren.cs.
  2. Write your own — create a MonoBehaviour that drives a Light component based on whatever logic you need. Don't modify RCC_Light.

For example, a beacon that flashes amber once per second:

public class WarningBeacon : MonoBehaviour {
    public Light beaconLight;
    public float flashRate = 1f;
    public float maxIntensity = 2f;

    void Update() {
        beaconLight.intensity = Mathf.PingPong(Time.time * flashRate, 1f) * maxIntensity;
    }
}

Next Steps