A whole city, generated: streets that go somewhere, traffic that obeys its own signals, people who only cross at crossings, a river with bridges, a railway with level crossings, weather, a day and a night.
Everything here is procedural. There are no meshes, no textures and no audio files in this package — the kit builds all of it from the seed you give it, so a city is a number you can put in a text field and a colleague can type the same number and see the same place.
To play in it, open Assets/CityKit/Demo/Scenes/CityDemo.unity and press Play. Keys 1, 2, 3 frame the city; 4 walks; 5 drives; 6 walks in third person, as one of the city's own people; F1 hides the panels. Nothing but those keys, the view buttons and the mouse moves the camera — changing a setting, pasting a code or pressing Rebuild leaves the viewpoint exactly where it was, so you can see what the change did.
The demo scene reads the legacy Input Manager. If your project's Project Settings > Player > Active Input Handling is set to Input System Package (New), the demo's keys and mouse do nothing — the city still generates and still runs, but you cannot fly, walk or drive in it. Set it to Both and the demo works alongside your own input code. Nothing outside Demo touches input at all, so if you delete the Demo folder this does not apply to you.
Everything the kit can do is reachable from Tools > City Kit > City Designer:
| Presets | 14 starting points, from Manhattan to Farmland. |
| Seed | The whole city is a function of this number. |
| Code | The whole city as one line of text. Paste one in and press Load. |
| Sliders | Every setting, each held to a range the generator actually honours. |
| Features | River, railway, coast. |
| Asset library | Your own prefabs (see Using your own art). |
| Export map PNG | A flat map of the city, written beside the project. |
| Save prefab | Keep the city you like. |
| Validation | What, if anything, is wrong with this city. |
A rebuild takes about 100 ms for a 96-cell city, 260 ms at 160 and 690 ms at 220, so the window waits for a drag to settle before rebuilding — never less than a quarter of a second, never more than a second and a half, and otherwise about as long as the last rebuild took. Turn off Rebuild while dragging if you would rather press the button yourself.
One component makes the whole city.
// One component makes the whole city.
var city = gameObject.AddComponent<CityView>();
// Required. Without it the city is drawn with a stand-in material and,
// in a built player, comes out flat white.
city.surfaceMaterial = surfaceMaterial;
city.settings.seed = 20260901;
city.settings.width = 96;
city.settings.height = 96;
city.Generate();
Change anything and generate again.
// Change anything and generate again. The old city is destroyed for
// you — there is no partial state to clean up.
view.settings.parkShare = 0.3f;
view.settings.maxFloors = 40;
view.Generate();
CityView also gives you Plan, Issues, PlanMs, BuildMs, Traffic, Pedestrians, Nav and Built. Set spawnTraffic, spawnPedestrians or bakeNavMesh to false before generating if you do not want them.
The plan is the city as data, and it is engine-free — you can generate and inspect one with no scene open.
// The plan is the city as data: every cell, road, lane and building.
CityPlan plan = view.Plan;
int parks = plan.CountKind(CellKind.Park);
Debug.Log(plan.Lots.Count + " buildings, " + parks + " park cells");
// Where is cell (10, 20) in world metres?
float wx, wz;
plan.CellToWorld(10, 20, out wx, out wz);
// Can a person stand here? Can a car drive here?
int cell = plan.Index(10, 20);
bool walkable = plan.IsWalkable(cell);
bool driveable = plan.IsDriveable(cell);
The ground plane is a partition: every cell has exactly one CellKind, one of Empty, Roadway, Sidewalk, Crosswalk, Lot, Park, Plaza, Water, Meadow — green land sealed off by the river, the railway or the map edge, which nothing can walk on — or Rail. Over it sit the graphs — Corridors (roads as centrelines), Intersections, Lanes, LaneLinks, Crossings, Signals, Blocks and Lots.
CityMovement answers "can something stand here" against the same cell rules the crowd and the navmesh use, so asking it means your object obeys the rule they do.
// Drop something on a pavement cell. CityMovement answers the same
// question for you that it answers for the crowd and the navmesh.
var plan = view.Plan;
var rng = new CityRng(plan.Seed);
for (int tries = 0; tries < 200; tries++)
{
int x = rng.Range(plan.Width), y = rng.Range(plan.Height);
if (!plan.IsWalkable(x, y)) continue;
float wx, wz;
plan.CellToWorld(x, y, out wx, out wz);
Instantiate(prefab, new Vector3(wx, CityMovement.GroundHeight(plan, x, y), wz),
Quaternion.identity);
break;
}
// A whole city as one line of text, safe to paste anywhere.
string code = CityCode.Encode(view.settings);
CitySettings loaded;
string error;
if (CityCode.TryDecode(code, out loaded, out error))
{
view.settings = loaded;
view.Generate();
}
else
{
Debug.LogWarning("That code is damaged: " + error);
}
A code is quantised on purpose — a code you cannot paste is a code nobody shares — so CityCode.Snap tells you the settings a code will actually reproduce. A damaged code is either refused or reproduces exactly the same city — what it will never do is quietly open a different one.
The kit checks its own work. A city that generates is not the same as a city that works, so the validator asks the questions a player would notice:
// Is this city actually a place? Every building fronting a street,
// the pavement one connected network, every lane reachable.
foreach (CityIssue issue in view.Issues)
Debug.Log(issue);
if (!CityValidation.IsUsable(view.Plan))
Debug.LogWarning("This seed produced a city with real problems.");
It reports if a building has no street to front onto, if the pavement is not one connected network, if a lane cannot be driven to, if a signal would give both axes green, or if a road crosses water with no bridge.
Every setting is held to a range, and the same table drives both the sliders and the generator — so a control can never offer a value that is silently replaced.
// What may a setting be? One table answers, and the generator reads
// the same one — so a slider built from this can never offer a value
// that is silently replaced.
foreach (SettingRange range in CitySettingsRange.All())
Debug.Log(range.Label + " (" + range.Group + "): "
+ range.Min + " to " + range.Max);
// Some ranges depend on the others.
float min, max;
CitySettingsRange.Effective(view.settings, "blockSpacingJitter", out min, out max);
| Setting | Range | What it does |
|---|---|---|
width, height | 40 – 220 | Cells across and down. |
cellSize | 2 – 8 | Metres per cell. 4 m is one realistic lane. |
blockSpacing | 8 – 30 | Cells between streets. |
blockSpacingJitter | 0 – 22 | How much that may vary. Capped by the room the spacing leaves. |
arterialEvery | 2 – 8 | Every Nth road gets two lanes each way. |
boulevardShare | 0 – 1 | Share of arterials given wide tree-lined pavements. |
riverWidth | 3 – 16 | Cells across the river. |
downtownRadius | 0 – 1 | Fraction of the map radius that builds towers. |
parkShare | 0 – 1 | Share of non-downtown blocks turned into parks. |
commercialShare | 0 – 1 | Of the rest, how much is shops rather than homes. |
maxFloors | 4 – 60 | Storeys for the tallest downtown tower. |
lotSetback | 0 – 2 | Cells from the pavement to the building line. Front gardens. |
maxLotSize | 2 – 10 | Largest footprint edge before a block is subdivided. |
carDensity | 0 – 40 | Cars per 100 roadway cells. |
pedestrianDensity | 0 – 40 | Pedestrians per 100 pavement cells. |
signalGreenSeconds | 3 – 30 | How long each axis holds green. The bottom of this range moves with the cell size: a walker has the green plus the all-red to cross four carriageway cells, so a bigger cell needs a longer green and the slider stops offering the ones that would strand somebody in the road. |
signalClearSeconds | 1 – 6 | The all-red gap where the junction empties. |
Thirteen things a city can be told not to contain. They are listed once in CityContentToggles, which is what the designer window draws and what the generator reads, and every one of them travels in a share code.
| Switch | Group | What it does |
|---|---|---|
river | Landscape | A river across the map, with bridges where roads cross it. |
railway | Landscape | A railway line with level crossings and a train. |
coast | Landscape | Open water along one edge, with a beach. |
trees | Streets | Street trees, park trees and the avenues along boulevards. |
lamps | Streets | Lamps down every kerb, and the haze around them after dark. |
streetFurniture | Streets | Benches, bins, hydrants, planters, post boxes, racks and signs — and the square's statue, flag poles and margin furniture. |
parkFeatures | Streets | Ponds, fountains, playgrounds and kiosks inside parks. |
busStops | Streets | Bus shelters. Without them there are no routes for buses to run. |
shopfronts | Streets | Lit shop windows on the ground floor of commercial buildings. |
hospital | Places | A hospital on a central block, with an ambulance bay. |
policeStation | Places | A police station out from the centre, with a yard of patrol cars. |
carParks | Places | Flat parking out of town and stacked decks downtown. |
citySquare | Places | A paved main square: a tiered fountain, a statue, a ring of flag poles, and a furnished margin of planters, benches, racks and lamps. |
footballPitch | Places | A marked pitch with goals, on the largest park that will hold one. |
beach | Places | Parasols, loungers and a lifeguard hut along the sand. Needs a coast. |
gardens | Places | Fences, hedges, sheds, greenhouses and pools behind low-rise homes. |
farms | Places | Fields on the outskirts, with bales and a grain silo. |
buses | Life | Buses running routes, stopping, and carrying people. Needs bus stops. |
twoWheelers | Life | Bicycles, motorcycles and scooters in the traffic. |
birds | Life | Flocks of birds over the city. |
groundAnimals | Life | Dogs walked on leads, and stray cats. |
Some of these change the city and some only add to it, and it is worth knowing which. The three landscape switches rebuild the map: with no river, the land it ran through becomes buildable and the blocks fall differently, so you get a different city rather than the same one minus a river. The Places switches change what stands on a block — with no hospital, that block goes back to shops.
The prop switches are the ones you can flick while looking at a city: placement is deterministic in the cell, so turning the benches off leaves every tree exactly where it was. What it will not promise is that no other number moves at all — a pond blocks cells, so removing the park features frees them and a couple more cats find somewhere to sit.
Turning twoWheelers off does not thin the traffic: a bicycle becomes the car it most resembles, so the same number of vehicles use the same roads.
Create a CityAssetLibrary (Assets > Create > City Kit > Asset Library) and drop it on the CityView. Every slot is optional: an empty one keeps the kit's own mesh, so you can re-skin a city one piece at a time and never have a half-finished city. Anything the library covers is instantiated as your prefab; anything it does not is merged into the kit's geometry as before.
Buildings are scaled to their lot and set on the ground, so a prefab does not have to be authored at any particular size.
The kit ships one library of its own: CityAssetLibraryHD under CityKit/ModelsHD, a high-detail set built with real cylinders, bevels and joinery — the street and park furniture, the square's statue and flag poles, the farm (tractor, silo, cows, scarecrow, bales, harrow), the four vehicle bodies in several paint colours each, all seven tree species, and the four building archetypes (houses, terraces, mid-rise blocks and towers, scaled to their lots). It ships assigned, so the demo opens in the HD look; the demo panel's Models > HD models toggle swaps back to the classic flat-shaded style, and in your own scene you assign it (or clear it) on the CityView the same way as any other library.
Trees have their own slots, one per species, because the planner chooses species by rule — willows only near water, maples for autumn — and a slot keyed only on "tree" would erase that. A library tree is placed with the kit's own per-spot size and stand, so the obstacle map stays honest.
Prefab conventions for your own models are the ones the HD set follows: +Z forward, feet on y = 0, an identity root rotation, and vertex colour with the alpha channel as the emissive mask. Fences, hedges and crops stay procedural in either mode — their geometry stretches with the cell size, which no fixed prefab can do.
People CAN be replaced, and keep the kit's animation when they are: a pedestrian prefab whose children are named LegL, LegR, KneeL and KneeR — legs pivoted at the hips (y = 0.86), knees at y = 0.46 — is walked, run, and sat on benches by the kit exactly like its own figures. The HD set's people are built this way. A prefab without those names is moved and turned as one object, for art with its own Animator.
The demo's drive mode has its own playerCar slot — a single prefab, +Z forward with wheels on y = 0, used as the car the player sits in; empty, the procedural player car returns.
Wildlife follows the same rule with its own part names. A bird prefab with children named WingL and WingR (pivoted at the shoulders) flaps in flight and folds its wings on the ground; a dog or cat prefab with LegFL, LegFR, LegBL, LegBR (pivoted at the hips) and Tail trots in diagonal pairs and wags. The library's birds, dogs and cats slots take any number of variants; leave a slot empty and that kind stays procedural — drawn as one live mesh in several coats, exactly as before.
The minimap in the demo panel and the exported PNG are drawn by one rule, so they always agree.
// A flat PNG of the city, drawn by the same rule as the minimap.
string error;
string path = CityMapTexture.WritePng(view.Plan, 8,
Application.persistentDataPath + "/city.png", out error);
if (path == null) Debug.LogWarning("No map: " + error);
Every CellKind has a colour, bridges and level crossings are drawn over the road they sit on, and building footprints are shaded by district. The colours are held at least 64 apart on some channel, because distinct and legible are not the same thing.
CityAudio mixes eight looping beds — city, traffic, rain, wind, birds, water, the level-crossing bell and a passing train — by where the listener is standing. Nothing is audible where its source is not: no park, no birds; no cars, no traffic; barriers up, no bell. The clips are generated, not shipped.
Pedestrians are simulated in CityCrowd, which has no Unity in it at all — CityPedestrians only draws what it decides. That split is why the crowd can be tested outside the engine.
People are not interchangeable. Each one has a build (slim, average, heavy), an age (adult or elderly), one of twelve faces, a walking speed that follows from those, and their own cadence and stride length. Some wear a hat, some carry a bag. A heavy person is a wider silhouette rather than a scaled-up slim one.
Speeds run from 1.25 m/s to about 1.9. The slowest figure is load-bearing: the signals must give that person long enough to cross the widest road in the city, so lowering it would lengthen the all-red at every junction. Elderly walkers are the slowest; everyone else is faster than them, rather than them being slower than everyone else.
Nobody just walks. Roughly a third of the time a person is doing something else, chosen from what is actually next to them:
| Activity | Where | Roughly |
|---|---|---|
| Stop and look | anywhere | 2–6 s |
| Sit / read | beside a bench | 14–40 s |
| Lie down / yoga | on grass | 20–60 s |
| Wait for a bus | beside a bus stop | 12–32 s |
| Window-shop | beside a newsstand or cafe | 6–16 s |
| Jog | anywhere | 15–55 s, at 1.55x speed |
Nobody stops on a crossing, and anyone caught out there when the phase ends runs for the far kerb at 1.75x speed rather than strolling.
Vehicle heads and pedestrian heads are different objects showing different things. A vehicle head has three lenses — red, amber, green — with one lit. A pedestrian head is shorter, at eye level, and shows a red standing figure or a green walking one; during the all-red after the walk phase it shows the green man dimmed, which means finish crossing but do not start.
Both are placed by CitySignalHeads in Core, so where they stand and which way they face is testable rather than incidental.
Some blocks get a purpose beyond housing, shops or grass. Which blocks, and which purpose, is decided by CityCivic in Core — deterministically, so a seed always puts the hospital in the same street.
| Place | Where it goes |
|---|---|
| City square | The most central block that will hold one. Banded paving, a tiered fountain, four corner benches, a statue on the long axis, a ring of flag poles, and a margin scattered with planters, benches, bins, racks and lamps. |
| Hospital | The next most central. Five to seven storeys, with a red ambulance apron. |
| Police station | Deliberately out from the centre, where there is room for a yard of patrol cars. |
| Car parks | Roughly one block in nine. Flat out of town; downtown stacks them into a deck. |
| Football pitch | The largest park that will hold one, either way round — parks here are long thin strips and so is a pitch. |
| Beach | Along the sand of the coast apron: parasols, loungers and a lifeguard hut. |
A civic block is not subdivided the ordinary way. The hospital, the station and the parking deck are ONE building over the whole block; the square, the pitch and the flat car parks are no building at all, just ground. They are also exempt from the rule that ties storeys to style — a five-storey hospital is a Block whatever the surrounding land is zoned as.
A block is only given a job if its rectangle is genuinely all its own land. A river or a corner can leave holes in a block, and a hospital half in the water is worse than a hospital one street over.
CityWildlife draws everything alive that is not a person or a vehicle. Put it anywhere in the scene:
var wildlife = new GameObject("Wildlife").AddComponent<CityWildlife>();
wildlife.view = city; // falls back to the CityView above it, or the first in the scene
wildlife.flockSize = 22; // birds
wildlife.birds = true; // and either half can be turned off
wildlife.animals = true;
A flock of birds circles the city as boids: keep apart, keep together, go the same way, and a goal that moves every fourteen seconds so the flock actually goes somewhere rather than milling on the spot. They climb over roofs — the skyline is one height per cell from CityBuildingHeights, and a bird looks at what is under where it is ABOUT to be, since at thirteen metres a second it covers most of a cell between frames.
Dogs belong to somebody. One walker in fourteen has one, and it casts about in front of and beside them on a lead two and a half metres long. The lead is a hard limit, not a target: an owner can turn a corner or break into a run, and a dog four metres away with a lead drawn between them reads as a bug however good the steering was.
Cats belong to nobody. They pick a spot within seven cells, saunter to it, and pick another — and they bolt when somebody comes within three and a half metres, because a cat that lets people walk through it is a prop.
CityFlock and CityAnimals in Core hold all of it; CityWildlife only draws the answer, as one mesh rebuilt each frame. Like every other per-frame system in the kit it has a public Rebuild(dt) that takes its own timestep, so it works in an editor tool where Unity runs no Update at all.
Bus stops are not scenery. Every arterial kerb carries shelters, and the stops along one kerb make a ROUTE — buses drive it, pull up at each stop in turn for six seconds, and carry the people who were waiting there.
A route is a LANE rather than a path through the city, which is the design decision everything else follows from. A lane already runs the whole length of its corridor and already wraps at the end, so a bus that drives its lane obeys every signal, junction and level-crossing rule the traffic model has, for free, and cannot invent a route the model does not believe in. Stops are staggered between the two kerbs of a road, so the two directions become two routes rather than one route driven backwards. A route with three or more stops gets two buses, started at opposite ends of the round so the gap between them is the gap between arrivals.
One thing does not come free: every other vehicle rolls for a turn at each junction, so a bus is marked to keep its lane. Without that it drives off its own route and then keeps stopping at positions that belong to the road it has left.
People waiting at a shelter board the first bus that stops, ride to another stop further along the same route, and get off there. A passenger is off the map while aboard: not drawn, not occupying a cell, and not counted in the census the drivers read — a rider left in it would be an invisible person standing in the road holding up the traffic.
CityBusNetwork in Core decides which stops belong to which lane and in what order; CityBusService runs the buses and moves the passengers. Both are engine-free, and the service has a public Advance(dt, now) like every other per-frame system in the kit. CityTraffic.Buses is the one on your city.
Buses are long, slow and in the kerb lane, and nothing overtakes in this model, so traffic queues behind one at a stop. That is deliberate — it is what a bus does — but it is the reason a city with buses runs slightly heavier than one without.
Eleven kinds of vehicle share the roads: saloon, van, bus, hatchback, estate, pickup, taxi, coupe, bicycle, motorcycle and scooter. The mix is one method — CityCarBody.Pick in Core — so the body sizes, the mix and the speeds all have exactly one definition, and the tests measure the same fleet you drive past. Each kind has its own body length, its own width and its own speed relative to the road's limit: a bus is the slowest and the longest, a coupe the quickest, a taxi carries a lit roof sign after dark. A bus is only ever dispatched down an arterial — it would block a one-lane street — and becomes a van anywhere else. A bicycle is the mirror image: it only appears on local streets, and becomes a motorcycle on an arterial, because nothing overtakes in this model and a 6 m/s bicycle in four lanes of through traffic is a rolling roadblock rather than a cyclist.
The three two-wheelers share the lanes rather than getting a rule of their own. Nothing filters past a queue here — a lane is single file and the collision test is one-dimensional along it — so a two-wheeler that tried to would be drawn inside the car beside it. They are shorter, they accelerate the same way, and a motorcycle is the quickest thing on the road. They also get their own, brighter paint: a two-wheeler is a tenth the bulk of a car and carries a rider tinted by the same colour, and the car palette's blacks turned the whole thing into an unreadable smudge.
If you want a different mix, CityCarBody.Pick is the one place to change it. Adding a kind means an entry in CityCarBody.HalfLength and HalfWidth, a case in CityMeshes.Car, and a share of the roll; the tests will tell you if you forget any of the three, including whether the kind ever actually reaches the road.
Seven tree species grow: broadleaf, poplar, conifer, bushy, blossom, willow and maple. The silhouette is the point — at the distance a city reads as a city you tell a poplar from a fir by its outline long before its colour — so each is a different shape rather than a different size. Streets and parks draw from different mixes: an avenue of poplars is a street, and a conifer belongs in a park. Maples carry autumn colour, which is the only warm foliage in the city.
Willows are the one species placed by the map rather than by a roll: they grow only within three cells of water, so a city with no river or lake grows none at all. They are also the one tree you cannot walk through — the foliage hangs almost to the ground, so the crowd goes around a willow where it walks under a broadleaf.
CityParticles is optional and off unless you add it. Put it beside CityView:
var particles = city.gameObject.AddComponent<CityParticles>();
particles.view = city;
particles.environment = environment; // without this, the lamp haze never comes on
particles.viewer = Camera.main; // falls back to Camera.main when empty
It draws two things:
Haze around the street lamps, which fades in with CityEnvironment.NightAmount and so is invisible by day. Three layers per lamp — a wide dim halo, a brighter core and a pool of light on the pavement — because a single quad reads as a pale ball rather than as light in the air. It is damped close up: a halo is drawn at a fixed size in metres, so undamped, standing under a lamp fills a third of the screen with wash.
Exhaust from the traffic. Only from cars that are actually moving, and only within exhaustRange of the camera, since nobody can see the rest. Puffs rise, drift with CityEnvironment.WindStrength, grow and thin.
Everything is one dynamic mesh with one material, so the whole effect is a single draw call however large the city. Nothing here feeds back into the simulation: removing the component changes how the city looks and nothing about how it behaves.
| Field | Default | What it does |
|---|---|---|
lampRange | 170 m | Lamps further than this get no haze. |
maxLamps | 110 | Most lamps hazed at once, nearest first. |
lampSize | 3.6 m | Diameter of the core halo. |
lampStrength | 0.55 | How strong the haze is at full night. |
exhaustRange | 70 m | Cars further than this do not smoke. |
maxPuffs | 260 | Ceiling on live puffs. |
puffLife | 1.8 s | How long one lasts. |
puffEvery | 0.20 s | Gap between puffs from one car. |
exhaustStrength | 0.42 | How opaque a fresh puff is. |
In a built player the particle shader has to be included, exactly like the surface shader: either keep a material that uses CityKit/CityParticle in a built scene, or add the shader to Project Settings → Graphics → Always Included Shaders. Without it the component says so once in the console and draws nothing — the city is unaffected otherwise.
Measured on a 220 x 220 city, the largest the kit builds:
| Plan | ~4 ms |
| Geometry | ~640 ms |
| Vertices | 1.49 M |
| Traffic model | 1.9 ms a frame at 900 cars |
The static geometry is cut into chunks so the renderer can cull it — merged whole, one mesh's bounds covered the entire map and looking down a single street still submitted every building in the city. Chunks too small on screen for their windows to read drop to plain massing, which is a sixth of the geometry and, at the distance it happens, indistinguishable.
The crowd and the traffic are capped: 900 cars and 700 people, whatever the density asks for. Both are drawn as ordinary renderers, so the engine culls the ones behind you.
Said plainly, because finding out later is worse:
roundabout needs lanes that end and hand their traffic on. It is understood and written up, not forgotten.
organic medieval tangle.
Runtime/Core | The city as data. No Unity in it at all — you can generate and test a city outside the engine. |
Runtime/Unity | Everything that turns a plan into a scene: meshes, audio, textures, traffic, crowd. |
Runtime/Shaders | Two shaders: the city surface, and the soft particle used for haze and exhaust. |
Editor | The designer window. |
Demo | The playable scene and its panels. Delete it if you do not want it. Nothing outside this folder references it, and nothing outside it reads input. |
Documentation | This file, and the samples in it as compiled code. |
You will not need most of the kit. These are the ones worth knowing about:
| Type | What it is for |
|---|---|
CityView | The one component. Generates and owns everything. |
CitySettings | What a city is generated from. |
CitySettingsRange | What each setting may be, and the sliders' source of truth. |
CityPlan | The finished city as data — cells, roads, lanes, blocks, buildings. |
CellKind | What occupies a cell. |
CityModel | Generates a plan with no scene and no Unity. |
CityPresets | The starting points, by name. |
CityCode | Cities as shareable text. |
CityValidation | Is this city usable, and if not, why. |
CityAssetLibrary | Your prefabs, slot by slot. |
CityMovement | Can something stand here — the rule the player, crowd and navmesh share. |
CityMapRenderer, CityMapTexture | The map, as data and as a PNG. |
CityAudio, CityAudioMix | The soundtrack and the rule behind it. |
CityParticles | Haze around the lamps after dark, and exhaust from the traffic. |
CityCrowd, CrowdWalker, CrowdActivity | The pedestrians, with no engine in them: who they are, where they step, and what they are doing. |
CityObstacles, CityPropFootprint | What is in the way on the pavement, and how much room it takes. |
CitySignalHeads, SignalAspect | Where signal heads stand, which way they look, and what each is showing. |
CityDecorPlanner, PropKind, TreeShape | What street furniture stands where, and which species a tree is. |
CityPopulation | How many cars and people a city gets. |
CityLod, CityChunking | What is drawn, and in how much detail. |
CityTextureFactory, CitySurface | The surface grain. |
CityRng | The deterministic random the whole kit uses. |
The city is grey, or flat white. Grey means the project is not on the Universal Render Pipeline: the shader is URP-only and falls back to a plain unlit material anywhere else. Flat white means no material was assigned — set CityView.surfaceMaterial to Assets/CityKit/Runtime/CityKitSurface.mat. The console says so too, but the city still draws, so it is easy to miss.
Nothing appears when I press Play. CityView.generateOnStart is off.
Pedestrians walk into the road. They cannot — they use the same rule the navmesh does. What you are seeing is a crossing.
A slider seems to be doing nothing. Two cases, and they are different.
If it stops responding near the top of its travel, that is a limit, and the kit will tell you which one. The river is capped to the map it crosses, so on a 96-cell city the width slider stops at 12 rather than offering four widths that all build the same river. The car and pedestrian densities are capped by a population budget of 900 cars and 700 people; past that point the demo panel reads at ceiling.
That budget is an absolute total, not a share of the map, so a bigger city does not carry more traffic — it reaches the same ceiling at a lower density. On a 96-cell city the cars slider stops mattering above about 40; on a 220-cell city it stops at about 7, so five sixths of its travel do nothing. If you want more than 900 cars you will need to raise the budget in CityPopulation.
If it seems to do nothing in the MIDDLE of its travel, that is usually quantisation. Boulevard share decides each arterial by itself, so on a map with six arterials it can only change six times, and small nudges land on the same city.
Anything else is a defect: a control that stops responding at either end of its travel, with no limit named above, is a bug and worth reporting.
Questions, bug reports and feature requests: szekipapa77@gmail.com
Please include your Unity version, render pipeline and the city seed or CITY CODE that reproduces the problem.