Ground Physics — Configuring Surfaces

This document explains how RCC handles different driving surfaces (asphalt, dirt, grass, sand, snow, ice), how to add your own surfaces, and how to fine-tune the feel of each.

RCC supports two parallel mechanisms for ground detection:

  1. PhysicMaterial-based — works on any collider in the scene. Just paint a PhysicMaterial onto a mesh or primitive collider.
  2. Terrain splatmap-based — works on Unity Terrain. Reads which paint texture is at the wheel's position.

Both are configured in the same asset: RCC_GroundMaterials.asset.

Why Multiple Surfaces Matter

A car on asphalt grips differently than a car on grass. Without surface-aware physics, your vehicle drives the same regardless of whether it's on the road or off it — which feels wrong and removes one of the most satisfying parts of driving games (the moment you go off-road and feel the loss of grip).

With ground materials, you get:

How the Lookup Works

When a wheel touches the ground, RCC reads the surface and looks it up in RCC_GroundMaterials.asset:

For Regular Colliders

1. Wheel raycasts down, hits a collider.
2. RCC reads the collider's `material` (its PhysicMaterial).
3. RCC searches the `frictions[]` array in RCC_GroundMaterials.asset for an entry with that PhysicMaterial.
4. The matched entry provides stiffness multipliers, audio, particles, skidmarks.
5. If no match is found, the wheel uses the entry at index 0 (the default).

For Unity Terrain

1. Wheel raycasts down, hits a TerrainCollider.
2. RCC reads the splatmap weights at that position.
3. RCC finds the dominant texture layer index.
4. RCC searches the `terrainFrictions[]` array for an entry whose `splatmapIndexes` array contains that index.
5. The matched entry provides the same fields as the PhysicMaterial path.

Opening the Ground Materials Asset

In the Project window, navigate to:

Assets/RealisticCarControllerV4/Resources/RCC Assets/RCC_GroundMaterials.asset

Click it. The Inspector shows two foldout sections:

Frictions (PhysicMaterial-based)

An array of GroundMaterialFrictions entries. Each entry has:

Field What It Does
Ground Material The PhysicMaterial this entry matches against.
Forward Stiffness Multiplier on the wheel's forward friction curve. 1.0 = full grip, 0.5 = half grip.
Sideways Stiffness Multiplier on the wheel's sideways friction curve.
Slip Base slip target for this surface.
Damp Damping force applied at this surface.
Volume Audio volume scalar (0–1).
Ground Particles Particle prefab spawned at the wheel when slipping on this surface.
Ground Sound Audio clip played at the wheel on this surface.
Skidmark Optional custom skidmark style.
Deflate If true, tires can deflate on this surface.

Terrain Frictions

An array of TerrainFrictions entries. Each one references a PhysicMaterial and lists which splatmap layer indexes use it.

Adding a New Surface

Let's add a "Snow" surface as a complete worked example.

Step 1 — Create a PhysicMaterial

In the Project window:

  1. Right-click in any folder → Create → Physic Material.
  2. Name it Snow.
  3. Set Dynamic Friction = 0.4, Static Friction = 0.4 (these are Unity's friction values, not RCC's — they affect Unity's general collision behavior).
  4. Set Friction Combine and Bounce Combine to Average.

Step 2 — Apply It to Your Snow Geometry

In your scene, find the mesh that represents snow ground (a mesh painted white, snow-piled terrain section, etc.). Click it. In the Inspector, find its MeshCollider (or BoxCollider). Drag your Snow.physicMaterial into the Material slot.

You can also apply the same PhysicMaterial to multiple colliders. All of them will trigger the same "Snow" behavior.

Step 3 — Add an Entry to RCC_GroundMaterials

Open RCC_GroundMaterials.asset. Expand the frictions[] array. Right-click the array → Add Element, or increase the Array Size by 1.

In the new entry:

Field Value Reason
Ground Material Drag your Snow.physicMaterial here. Tells RCC which PhysicMaterial this entry corresponds to.
Forward Stiffness 0.4 Snow is slippery — only 40% of asphalt grip.
Sideways Stiffness 0.3 Even less sideways grip.
Slip 0.3 A bit easier to break loose.
Damp 1.0 Default damping.
Volume 0.3 Snow audio is quiet — soft crunch.
Ground Particles Drag a snow-particle prefab here, or leave empty. Optional white spray when sliding.
Ground Sound Drag a snow audio clip here. Soft crunch / spray sound.
Skidmark Leave empty for default. Default looks fine on snow.
Deflate False Snow doesn't puncture tires.

Save the asset (Ctrl+S or close the inspector).

Step 4 — Test

Open a scene with snow geometry, press Play, drive onto the snow. You should immediately feel reduced grip and hear the new audio.

If nothing changes, the most likely cause is that the collider's PhysicMaterial slot is empty or assigned a different material. Verify in the Inspector.

Adding a Terrain Surface

If your snow lives on Unity Terrain instead of a separate mesh:

Step 1 — Paint Snow on the Terrain

In Unity Terrain Inspector, use the paint tool to paint a snow texture on the terrain layer of your choice. Note which layer index snow is in (the order in the Terrain Layers list — usually 0 is grass, 1 is dirt, etc.).

Step 2 — Create a PhysicMaterial

Same as Step 1 above — create a Snow.physicMaterial.

Step 3 — Add a Terrain Friction Entry

In RCC_GroundMaterials.asset, expand the terrainFrictions[] array. Add an element.

Field Value
Ground Material Your Snow.physicMaterial.
Splatmap Indexes Array of one element with index = 1 (or whichever layer snow is at on your terrain).

If your snow can appear in multiple terrain layers (e.g., layer 1 and layer 3), add both indexes to the splatmapIndexes array.

The terrain lookup uses the dominant texture at the wheel's position. So a wheel partially on snow and partially on grass will trigger whichever is more dominant at that moment.

Existing Default Surfaces

The default RCC_GroundMaterials.asset ships with entries for:

You can edit the values on these entries to taste — the defaults are starting points, not gospel.

Adjusting Default Surfaces

If asphalt feels too grippy or grass too slippery, you can adjust the stiffness without changing anything else:

  1. Open RCC_GroundMaterials.asset.
  2. Find the entry for the surface you want to change.
  3. Adjust Forward Stiffness and Sideways Stiffness.
  4. Test in Play mode.

A good rule of thumb:

Surface Forward Sideways Reasoning
Race track asphalt 1.5 1.5 High grip, race tires.
Normal asphalt 1.0 1.0 Default reference.
Wet asphalt 0.7 0.6 Reduced grip.
Dirt 0.6 0.5 Loose surface.
Grass 0.4 0.3 Slippery.
Sand 0.5 0.4 Resistance + low grip.
Snow 0.4 0.3 Slippery.
Ice 0.1 0.1 Almost no grip.
Mud 0.3 0.2 Slip + drag.

Custom Skidmarks per Surface

For full visual control, you can give a surface its own skidmark style. Drag a custom RCC_Skidmarks component prefab into the Skidmark field of the ground material entry. This is how, for example, snow skidmarks can look different from asphalt skidmarks.

If you don't assign a custom skidmark, the surface uses the default RCC_SkidmarksManager settings (configured in RCC_Settings.asset).

Tire Deflation Surfaces

To create a "broken glass" or "spike strip" surface that punctures tires:

  1. Create the PhysicMaterial.
  2. Apply it to the collider.
  3. In the ground material entry, set Deflate = true.
  4. Set Forward Stiffness and Sideways Stiffness very low (0.1–0.2) since flat tires reduce grip.

When a wheel touches a deflate-true surface, the tire flattens after a short delay. The vehicle handles poorly until repaired via RCC.Repair(carController).

Audio Clips

A few notes on audio clips for ground surfaces:

The volume field is multiplied with the default RCC audio mixer level, so 1.0 = mixer default, 0.5 = quieter.

Particle Effects

Ground particle prefabs are placed at the wheel transform and emit while the wheel is on this surface and slipping. You can use:

The emission rate scales with slip — a stationary wheel emits no particles, a heavily-spinning wheel emits maximum particles.

Performance Considerations

Each wheel does one raycast per FixedUpdate. The cost is small but multiplied by:

For very large scenes with many AI vehicles:

Common Issues

"I added a surface but nothing changed"

Most likely the collider doesn't have your PhysicMaterial assigned. Double-check the collider's Material slot in the Inspector.

If you added a terrain surface, check that the splatmap index in your TerrainFrictions entry matches the actual terrain layer order. If you paint a new texture, its index might be different from what you expect.

"The same surface behaves differently in different scenes"

This usually means the PhysicMaterial is duplicated. In Project view, search for the material name — you might have two Snow.physicMaterial files in different folders. RCC matches by reference, so the same-name-but-different-asset materials are treated as different surfaces. Consolidate to one.

"The default surface is used even though my collider has a PhysicMaterial"

Check that the PhysicMaterial is referenced in RCC_GroundMaterials.asset. The lookup is "find an entry whose groundMaterial field equals this collider's material." If no entry references the material, the fallback (index 0) is used.

Next Steps