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.
Road pipeline
Section titled “Road pipeline”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]
1. Change grid size
Section titled “1. Change grid size”Two grid values matter in the shipped template:
| Blueprint | Property | Shipped default | Role |
|---|---|---|---|
| BP_CBT_PlayerController | Grid Size | 200 | Placement snap for buildings and roads |
| BP_CBT_Grid | Default Grid Size | 100 | Visual grid cell size |
| BP_CBT_Grid | Grid Divisions | 4 | Subdivisions per cell |
- Open
Blueprints/Misc/BP_CBT_Grid(placed in DemoMap) to change the visual grid. - Open BP_CBT_PlayerController → Class Defaults to change placement snap (Grid Size).
- Compile and verify BFL_CBT_GlobalFunctions → GridSnap_Float still aligns previews.
Example — finer placement
| Setting | Shipped default | Example |
|---|---|---|
| Grid Size (controller) | 200 | 100 for half-cell placement snap |
| Default Grid Size (grid actor) | 100 | Match controller or keep visual grid separate |
Rebuild a test road and house after changing either value.
2. Road meshes and materials
Section titled “2. Road meshes and materials”BP_RoadTile properties:
| Property | Purpose |
|---|---|
| RoadMeshComponent | Instanced mesh per tile |
| RoadType | ERoadType → mesh selection |
| Materials | Set on mesh or via CreateDynamicMaterialInstance |
Example — wider roads
- Duplicate the straight road static mesh under
Meshes/(or scale in mesh asset). - Assign the new mesh on BP_RoadTile for ERoadType::Straight.
- Update BP_Road → PreviewRoad mesh to match.
3. Intersections and lamps
Section titled “3. Intersections and lamps”BP_RoadTile graph functions:
| Function | Role |
|---|---|
| Internal_UpdateRoadType | Picks straight vs corner vs Fourway from neighbours |
| Internal_UpdateToFourwayIfRequired | Promotes crossing tiles |
| Internal_AddLampToStraightRoad | Spawns lamp mesh on straights |
To disable street lamps, clear or bypass Internal_AddLampToStraightRoad on BP_RoadTile.
Example — four-way only intersections
- Open BP_RoadTile Event Graph.
- Trace Internal_UpdateRoadType branches.
- Force Fourway only when ≥3 neighbours connect; otherwise keep Straight.
4. Road placement UX
Section titled “4. Road placement UX”BP_CBT_PlayerController:
| Property / function | Tweak |
|---|---|
| bShowRoadDebugSpheres | Visualize snap points while learning |
| Internal_PreviewRoad / ClearPreviewRoad | Ghost colour/material |
| CreateRoad | Finalize and deduct currency (if wired) |
BP_Road:
| Function | Tweak |
|---|---|
| SetSplinePoints | Point density along curves |
| RemoveSplinePoint | Undo last click |
5. Ambient traffic
Section titled “5. Ambient traffic”BP_Vehicle drives on BP_RoadTile chains.
| Function | Behaviour |
|---|---|
| Internal_TraceForRoadTile | Finds next tile |
| Internal_PlayTimeline | Moves along spline |
| Internal_OnDayStarted / Internal_OnNightStarted | Visibility with day cycle |
Example — fewer vehicles at night
- Open BP_Vehicle.
- On Internal_OnNightStarted, pause or hide mesh (pattern already present — tune timers).
- Confirm BP_CBT_SaveGame → AddVehicle still restores traffic on load.
6. Collision channel
Section titled “6. Collision channel”Roads use GenericRoad (ECC_GameTraceChannel2). Building placement traces GenericBuilding against road overlaps.
If custom meshes fail placement checks:
- Verify mesh collision profile = GenericRoad or GenericBuilding.
- Confirm
Config/DefaultEngine.inichannel definitions are migrated (see Migrate tutorial).
Example presets
Section titled “Example presets”| Preset | Grid Size (controller) | Road notes |
|---|---|---|
| Compact city | 100 | Shorter BP_Road spline segments |
| Highway layout | 200 (default) | Wider straight mesh, disable lamps |
| Pedestrian plaza | 300+ | Fewer tiles; rely on large commercial footprints |
Test checklist
Section titled “Test checklist”- Draw an L-shaped road — corner tile updates via Internal_UpdateRoadType.
- Place a House on a cell touching GenericRoad — bIsNearRoad = true.
- Bulldoze a middle tile — neighbouring tiles refresh type.
- Save, reload, confirm RoadSaveArray restores mesh variants.