Ground Materials

Table of Contents

RCCP uses PhysicMaterial-based surface detection to vary friction, particles, sounds, and skidmarks depending on what surface the wheels are touching. Every ground collider in your scene can be mapped to a set of surface properties, and Unity Terrains are supported through splatmap-based detection.

For general project setup, see Installation. For vehicle configuration, see Vehicle Setup.


Overview

The ground materials system works as follows:

  1. Each wheel checks which PhysicMaterial is on the collider it is touching.
  2. The system looks up that PhysicMaterial in the RCCP_GroundMaterials asset.
  3. If a match is found, the corresponding friction, particle, sound, and skidmark settings are applied to that wheel.
  4. For Unity Terrains, the system reads the splatmap to determine which terrain texture has the highest weight at the wheel's position, then maps that texture to a PhysicMaterial.

RCCP_GroundMaterials ScriptableObject

RCCP_GroundMaterials is a singleton ScriptableObject loaded from the Resources folder. Access it at runtime via:


RCCP_GroundMaterials groundMats = RCCP_GroundMaterials.Instance;

The asset is located at:


Assets/Realistic Car Controller Pro/Resources/RCCP_GroundMaterials.asset

It contains two main arrays:

ArrayTypePurpose
frictionsGroundMaterialFrictions[]Per-surface settings for regular colliders
terrainFrictionsTerrainFrictions[]Splatmap-to-PhysicMaterial mappings for terrains

GroundMaterialFrictions

Each entry in the frictions array defines how a specific surface type behaves. Here are all the fields:

FieldTypeDefaultDescription
groundMaterialPhysicsMaterial(none)The Unity physics material assigned to ground colliders. This is the key used for surface matching.
forwardStiffnessfloat1Affects braking and acceleration grip. Higher values mean more grip along the wheel's forward axis.
sidewaysStiffnessfloat1Affects cornering grip. Higher values mean less lateral sliding.
slipfloat0.25Slip threshold before particles and skidmarks begin to appear. Lower values make effects trigger sooner.
dampfloat1Damping force applied to the wheel on this surface.
volumefloat1Volume of the tire-on-surface sound (range 0 to 1).
groundParticlesGameObject(none)Particle prefab to spawn when the wheel slips on this surface (dust, gravel, snow, etc.). Must have or will receive an RCCP_WheelSlipParticles component.
groundSoundAudioClip(none)Audio clip played when the wheel rolls on this surface.
skidmarkRCCP_Skidmarks(none)Skidmark prefab used to draw tire marks on this surface.

Note on PhysicsMaterial vs PhysicMaterial: In Unity 2023.3 and newer (including Unity 6), the type is PhysicsMaterial. In older versions, it is PhysicMaterial. RCCP handles this automatically with preprocessor directives.

Example Configurations

SurfaceforwardStiffnesssidewaysStiffnessslipdampParticlesSound
Asphalt1.01.00.251.0None or light smokeTire hum
Gravel0.70.70.150.8Gravel dustCrunching gravel
Grass0.50.50.10.6Grass/dirt particlesSoft rolling
Sand0.40.40.10.5Sand spraySand whoosh
Ice0.150.150.050.3NoneIce scrape

Setting Up a New Surface

Follow these steps to add a new ground surface type:

Step 1: Create a PhysicMaterial

  1. In the Unity Project window, right-click and select Create > Physic Material (or Physics Material in Unity 6).
  2. Name it descriptively (for example, PM_Gravel).
  3. Configure its friction and bounciness values as needed.

Step 2: Assign It to Your Ground Collider

  1. Select the ground GameObject in your scene (a MeshCollider, BoxCollider, etc.).
  2. In the Inspector, find the collider component.
  3. Drag your new PhysicMaterial into the Material field of the collider.

Step 3: Open the Ground Materials Asset

  1. Navigate to Assets/Realistic Car Controller Pro/Resources/.
  2. Select RCCP_GroundMaterials.asset.
  3. Alternatively, open it from the menu: Tools > BoneCracker Games > Realistic Car Controller Pro > Configuration > Ground Physics Materials.

Step 4: Add a New Friction Entry

  1. In the Inspector for RCCP_GroundMaterials, find the Frictions array.
  2. Increase the array size by 1.
  3. In the new entry, assign your PhysicMaterial to the groundMaterial field.

Step 5: Configure the Entry

  1. Set forwardStiffness and sidewaysStiffness to control grip.
  2. Adjust slip to control when visual effects begin.
  3. Set damp for the surface damping.
  4. Assign a particle prefab to groundParticles (optional).
  5. Assign an audio clip to groundSound (optional).
  6. Assign a skidmark prefab to skidmark (optional).

Step 6: Validate Particle Prefabs

RCCP_GroundMaterials includes a CheckWheelPrefabsForMissingScript() method that ensures all assigned particle prefabs have the required RCCP_WheelSlipParticles component. This is called automatically, but you can trigger it manually if needed.


Terrain Support

RCCP supports Unity Terrains through splatmap-based surface detection. Instead of using a single PhysicMaterial for the entire terrain, the system checks which terrain texture (layer) has the highest weight at each wheel's position and maps it to the corresponding ground material.

How It Works

  1. On scene start, RCCP_SceneManager calls GetAllTerrains() to find and cache all Terrain.activeTerrains.
  2. For each terrain, the following data is cached in a Terrains class:
FieldDescription
terrainReference to the Unity Terrain component
mTerrainDataCached TerrainData for alphamap access
terrainColliderPhysicMaterial from the terrain's TerrainCollider
alphamapWidthWidth of the terrain alphamap in pixels
alphamapHeightHeight of the terrain alphamap in pixels
mSplatmapDataFull alphamap array [x, y, textureIndex]
mNumTexturesNumber of terrain texture layers
  1. At runtime, each wheel that detects it is on a terrain surface reads the cached splatmap data to find which texture has the highest weight at its world position.
  2. The TerrainFrictions entries in RCCP_GroundMaterials map terrain layer indexes to PhysicMaterials.

TerrainFrictions Configuration

The terrainFrictions array in RCCP_GroundMaterials contains entries with:

FieldTypeDescription
groundMaterialPhysicsMaterialThe PhysicMaterial that this terrain layer maps to. Must match an entry in the frictions array.
splatmapIndexesSplatmapIndexes[]Array of terrain texture layer indexes that use this PhysicMaterial.

Each SplatmapIndexes entry has a single field:

FieldTypeDescription
indexintThe terrain layer index (starting at 0) in the terrain's texture list.

Setting Up Terrain Surfaces

  1. Open RCCP_GroundMaterials.asset.
  2. In the Terrain Frictions array, add one entry per surface type present on your terrain.
  3. For each entry:
  1. Make sure the PhysicMaterial on the TerrainCollider is also present in the frictions array as a fallback.

Example

Suppose your terrain has three layers:

Layer IndexTextureDesired Surface
0GrassGrass (low grip)
1Dirt PathGravel (medium grip)
2RockAsphalt (high grip)

You would create three terrainFrictions entries, each pointing to the appropriate PhysicMaterial (which must also have a matching entry in the frictions array with particles, sounds, and skidmarks configured).


Skidmarks System

Skidmarks are the tire marks left on the ground when wheels slip. RCCP uses a shared manager to handle all skidmark rendering.

Architecture

ComponentRole
RCCP_SkidmarksManagerSingleton manager. Creates one RCCP_Skidmarks instance per ground material at scene start. Routes wheel slip data to the correct skidmark instance.
RCCP_SkidmarksThe actual skidmark renderer. Uses a ring buffer of MarkSection entries and dynamically builds a mesh. Supports both multithreaded and single-threaded mesh generation.

How Skidmarks Are Generated

  1. RCCP_SkidmarksManager instantiates one RCCP_Skidmarks prefab per entry in the frictions array on Awake.
  2. When a wheel slips, it calls RCCP_SkidmarksManager.Instance.AddSkidMark() with:
  1. The skidmark prefab builds quad strips from connected sections, stored in a ring buffer with a maximum of maxMarks sections (default 1024).

Skidmark Prefab Settings

Each RCCP_Skidmarks prefab on the skidmark GameObject has:

PropertyDefaultDescription
maxMarks1024Maximum number of mark sections before the ring buffer wraps
groundOffset0.02Height above the surface in meters to prevent z-fighting
minDistance0.04Minimum distance between consecutive sections. Closer sections are skipped.

Cleaning Skidmarks at Runtime


// Clean all skidmarks in the scene
RCCP.CleanSkidmarks();

// Clean skidmarks for a specific ground material index
RCCP.CleanSkidmarks(0); // Cleans skidmarks for the first ground material

These methods call through to RCCP_SkidmarksManager.Instance.CleanSkidmarks(), which resets the mark counter and triggers a mesh rebuild.

Performance Notes


Common Issues

No Skidmarks on a Surface

Wrong Particles or Sounds on a Surface

Terrain Surface Not Detected

Particles Do Not Appear

Skidmarks Flicker or Z-Fight


Related Topics


Support: bonecrackergames@gmail.com | www.bonecrackergames.com

Need help? See Troubleshooting