Skip to content

Customize roads and grid

Roads and the placement grid define where buildings can exist. This tutorial covers BP_CBT_Grid, BP_Road, BP_RoadTile, and BP_Vehicle.

flowchart TD
  Input[PrimaryClick on BP_Road spline] --> Preview[PreviewRoad mesh]
  Preview --> Create[CreateRoad]
  Create --> Tile[Spawn BP_RoadTile per point]
  Tile --> Type[Internal_UpdateRoadType]
  Type --> Save[AddRoadToSave]
  Tile --> Traffic[BP_Vehicle traces tiles]

Two grid values matter in the shipped template:

BlueprintPropertyShipped defaultRole
BP_CBT_PlayerControllerGrid Size200Placement snap for buildings and roads
BP_CBT_GridDefault Grid Size100Visual grid cell size
BP_CBT_GridGrid Divisions4Subdivisions per cell
  1. Open Blueprints/Misc/BP_CBT_Grid (placed in DemoMap) to change the visual grid.
  2. Open BP_CBT_PlayerController → Class Defaults to change placement snap (Grid Size).
  3. Compile and verify BFL_CBT_GlobalFunctions → GridSnap_Float still aligns previews.

Example — finer placement

SettingShipped defaultExample
Grid Size (controller)200100 for half-cell placement snap
Default Grid Size (grid actor)100Match controller or keep visual grid separate

Rebuild a test road and house after changing either value.

BP_RoadTile properties:

PropertyPurpose
RoadMeshComponentInstanced mesh per tile
RoadTypeERoadType → mesh selection
MaterialsSet on mesh or via CreateDynamicMaterialInstance

Example — wider roads

  1. Duplicate the straight road static mesh under Meshes/ (or scale in mesh asset).
  2. Assign the new mesh on BP_RoadTile for ERoadType::Straight.
  3. Update BP_Road → PreviewRoad mesh to match.

BP_RoadTile graph functions:

FunctionRole
Internal_UpdateRoadTypePicks straight vs corner vs Fourway from neighbours
Internal_UpdateToFourwayIfRequiredPromotes crossing tiles
Internal_AddLampToStraightRoadSpawns lamp mesh on straights

To disable street lamps, clear or bypass Internal_AddLampToStraightRoad on BP_RoadTile.

Example — four-way only intersections

  1. Open BP_RoadTile Event Graph.
  2. Trace Internal_UpdateRoadType branches.
  3. Force Fourway only when ≥3 neighbours connect; otherwise keep Straight.

BP_CBT_PlayerController:

Property / functionTweak
bShowRoadDebugSpheresVisualize snap points while learning
Internal_PreviewRoad / ClearPreviewRoadGhost colour/material
CreateRoadFinalize and deduct currency (if wired)

BP_Road:

FunctionTweak
SetSplinePointsPoint density along curves
RemoveSplinePointUndo last click

BP_Vehicle drives on BP_RoadTile chains.

FunctionBehaviour
Internal_TraceForRoadTileFinds next tile
Internal_PlayTimelineMoves along spline
Internal_OnDayStarted / Internal_OnNightStartedVisibility with day cycle

Example — fewer vehicles at night

  1. Open BP_Vehicle.
  2. On Internal_OnNightStarted, pause or hide mesh (pattern already present — tune timers).
  3. Confirm BP_CBT_SaveGame → AddVehicle still restores traffic on load.

Roads use GenericRoad (ECC_GameTraceChannel2). Building placement traces GenericBuilding against road overlaps.

If custom meshes fail placement checks:

  1. Verify mesh collision profile = GenericRoad or GenericBuilding.
  2. Confirm Config/DefaultEngine.ini channel definitions are migrated (see Migrate tutorial).
PresetGrid Size (controller)Road notes
Compact city100Shorter BP_Road spline segments
Highway layout200 (default)Wider straight mesh, disable lamps
Pedestrian plaza300+Fewer tiles; rely on large commercial footprints
  1. Draw an L-shaped road — corner tile updates via Internal_UpdateRoadType.
  2. Place a House on a cell touching GenericRoadbIsNearRoad = true.
  3. Bulldoze a middle tile — neighbouring tiles refresh type.
  4. Save, reload, confirm RoadSaveArray restores mesh variants.