FAQ & Common Mistakes

This page collects the questions that come up most often when developers reskin Traffic Overtaker into their own one-button overtaking game, together with the mistakes that cost the most time. Every answer is grounded in the actual shipping code — chiefly Assets/TO/Scripts/TO_Player.cs, the TO_Settings ScriptableObject, and the editor tooling under Assets/TO/Editor/. The asset uses the TO_ class prefix inside the BoneCrackerGames namespace, and the bundled physics engine keeps the RCCP_ prefix and stays global (Realistic Car Controller Pro). When in doubt about a concrete value, open the file named in the answer rather than trusting a remembered default — the inspector and the .asset are the single source of truth.

The questions are grouped into five categories so you can jump straight to the area you are stuck on: Getting Started, Vehicles, Scenes, Scoring & Economy, and Troubleshooting. Several answers cross-reference the deeper pages in this set; follow those links when you need the full procedure rather than the short answer.

Getting Started

Where do I begin after importing the asset?

Traffic Overtaker ships as a complete project, not a drop-in package, so the first thing to do is open the Welcome Window (it auto-opens on first import, or via Tools > BoneCracker Games > Traffic Overtaker > Welcome Window) and confirm the one-time setup. That setup ensures the BCG_TO scripting define symbol is present, the four gameplay scenes are in Build Settings, and the render pipeline is configured for URP in linear color space. Once the project compiles cleanly with zero console errors, open TO_Scene_MainMenu and press Play to confirm the showroom and a gameplay run both work end to end before you change anything. See 02_Installation.md for the full first-run checklist.

Which scenes are actually built into the game?

Only four scenes are enabled in Build Settings: TO_Scene_MainMenu, TO_Scene_Sunny, TO_Scene_Rainy, and TO_Scene_Night. Two template scenes (TO_SceneTemplates/TO_SceneTemplate_Mainmenu and TO_SceneTemplates/TO_SceneTemplate_Gameplay) plus TO_Scene_CarCreate are present in the build list but disabled — the templates are starting points you duplicate, not scenes the player ever loads. The mainMenuSceneIndex field in TO_Settings is 0, which must stay pointing at the main menu scene's build index. See 05_Scenes.md for the scene roster and 10_ReskinningScenes.md for the duplication workflow.

Should I work in the gameplay scenes or the templates?

Build new content from the template scenes whenever you can. TO_SceneTemplate_Gameplay already contains a correctly wired manager stack (TO_SceneManager, TO_GameplayManager, TO_CurvedRoadManager, TO_PathManager, TO_TrafficManager, TO_LaneManager, the camera, and both UI canvases), so duplicating it guarantees you start from a known-good configuration. Editing TO_Scene_Sunny directly is fine for quick reskins, but if you accidentally delete a manager you will hit null-reference errors at runtime that are tedious to trace. The recovery path for either case is the Check & Create All Managers button described in the Scenes section below.

Vehicles

How do I add my own car?

You cannot add a bare mesh — a player vehicle in Traffic Overtaker is a fully configured RCCP vehicle first, and a Traffic Overtaker car second. TO_Player declares [RequireComponent(typeof(RCCP_CarController))] and [RequireComponent(typeof(Rigidbody))], so the car must already have a working RCCP drivetrain (engine, axles, wheels, differential) before the TO_Player component will function at all. Build that RCCP vehicle first using the How To Build An RCCP Vehicle button — it appears on the TO_Player component inspector (it calls TO_EditorWindows.OpenRCCPVehicleSetupDoc(), opening the bundled doc Assets/TO/Realistic Car Controller Pro/Documentation/HTML/03_vehicle_setup.html), at the Configure Player Cars "Select A RCC Based Car" error, and in the Welcome window's DOC tab.

Once the RCCP vehicle drives correctly, add TO_Player, then use the inspector buttons: Create Prefab saves it to Assets/TO/Prefabs/Player Vehicles/, and Add Prefab To Player Vehicles List registers it in the TO_PlayerCars roster so it shows in the showroom. The full step-by-step lives in 06_PlayerVehicles.md.

How many cars ship with the asset, and how are they unlocked?

The TO_PlayerCars roster contains 14 player vehicles. Index 0 (E30, prefab M5_E30) is free and unlocked; the other 13 are locked behind a Currency price ranging from ₵15,000 up to ₵45,000 for the top car (CTR). Ownership is stored in PlayerPrefs under the key {VehicleName}OwnedTO_API.UnlockVehicle() writes it and TO_API.OwnedVehicle(index) reads it. If you change a vehicle's prefab name, remember that the owned-flag key is derived from playerCar.name, so renaming a prefab effectively resets its purchase state. See 06_PlayerVehicles.md and 09_Customization.md.

Why are the customization buttons greyed out for one of my cars?

The showroom enables the paint / wheel / spoiler / NOS customization buttons only when the selected vehicle actually carries the corresponding RCCP component. As the TO_Player inspector help box states, a vehicle "must be equipped with the Customizer to use customization features. Otherwise, the customization buttons in the main menu will be disabled for this vehicle," and NOS requires the NOS add-on under the vehicle's Other Addons component. So a disabled button is usually a missing RCCP_Customizer or upgrade component on the prefab, not a UI bug. The wheel options come from RCCP_ChangableWheels, which currently holds 7 upgradable wheel entries — see 09_Customization.md.

Scenes

How do I make a new gameplay scene?

Duplicate TO_SceneTemplate_Gameplay, rename the copy (for example TO_Scene_Desert), reskin the environment art, then add the new scene to Build Settings. If any manager ends up missing — for instance after merging scene changes or deleting an object by mistake — select the TO_SceneManager object and use the inspector to repair it: each manager has a status button that is GREEN when found and RED when missing, and clicking a red one creates that manager. The Check & Create All Managers button does the whole stack in one click (Gameplay Manager, Curved Road Manager, Path Manager, Traffic Manager, Lane Manager, Player Camera, UI Gameplay, UI Gameover, UI Event System, RCCP Scene Manager). Set the Level Type dropdown to Gameplay (versus Mainmenu) so the right manager set is validated. The full reskin walkthrough is in 10_ReskinningScenes.md.

My new scene loads but nothing spawns — what's wrong?

The most common cause is a scene that is missing one or more managers, or one that was created from a blank scene instead of the template. TO_Player early-outs of almost all of its logic when TO_GamePlayManager is absent (if (!GameplayManager) return;), so a missing gameplay manager looks like "the game does nothing." Open TO_SceneManager, confirm every status button is green, and run Check & Create All Managers if any is red. Also confirm the scene is enabled in Build Settings and not just present on disk.

Why does the world snap back toward the origin during a long run?

That is intentional — the gameplay scenes contain a TO_FixFloatingOrigin object that periodically shifts everything back toward world origin to keep physics precise during the endless run. TO_Player.OnFloatingOriginShift(Vector3 offset) compensates the distance bookkeeping so your traveled-distance score stays continuous across the shift. If you build a custom gameplay scene and omit this object, very long runs will start to jitter as floating-point precision degrades far from the origin. Keep the TO_FixFloatingOrigin object in any gameplay scene you author.

Scoring & Economy

Where do I change scoring / money?

There are two layers, and knowing which is which saves a lot of confusion. The tunable numbers (multipliers, thresholds, and point values) live in the TO_Settings ScriptableObject at Resources/TO_Settings.asset; the scoring logic that consumes them lives in TO_Player.cs. The live values are:

TO_Settings field Live value Used by
minimumSpeedForGainScore 80 km/h Score and overtake/near-miss gating in TO_Player.Update() / CheckOvertakes()
minimumSpeedForHighSpeed 140 km/h High-speed time accrual in TO_Player.Update()
overtakePoints 250 TO_Player.RegisterOvertake()
overtakeChainCap 10 Combo cap in RegisterOvertake()
oncomingNearMissMultiplier 4 Bonus weight in RegisterNearMiss()
overtakeMoneyMP 120 Dominant money payout (overtakes * overtakeMoneyMP) in TO_Player.GameOver()
totalNearMissMoneyMP 30 Near-miss money payout in GameOver()
totalDistanceMoneyMP 40 Distance money payout in GameOver()
totalOverspeedMoneyMP 20 Legacy — high-speed time is no longer converted to currency, so this is currently unused
initialMoney 20000 Starting Currency

A successful overtake is detected in CheckOvertakes() (a same-direction car that was clearly ahead falls clearly behind) and scored in RegisterOvertake() as overtakePoints * chain, where chain is the near-miss/overtake combo clamped to overtakeChainCap. A near-miss is scored in RegisterNearMiss(), and squeezing past oncoming traffic multiplies the points by oncomingNearMissMultiplier. At game over, TO_Player.GameOver() converts overtake count, near-miss count, and distance into Currency via TO_API.AddCurrency() (high-speed time is no longer a currency source).

Where do I tune the scoring values in the TO_Settings inspector?

The custom TO_Settings inspector surfaces every scoring field — a newly-added serialized field can never silently disappear (anything not explicitly placed falls through to an Other (unmapped) section). The money multipliers live under Score Multipliers: totalDistanceMoneyMP, totalNearMissMoneyMP, totalOverspeedMoneyMP, and overtakeMoneyMP (four of them). The in-run scoring/risk fields — overtakePoints, overtakeChainCap, oncomingNearMissMultiplier, passiveScoreRate, and headOnFrontalDot — are drawn under an Overtake Scoring & Risk section. See 12_EditorTools.md for the full inspector layout.

How is high score / currency persisted, and how do I reset it during testing?

All persistence is PlayerPrefs. The keys you will touch most are Currency (player money), bestScoreOvertake (endless high score), {VehicleName}Owned (per-car unlock), and SelectedPlayerCarIndex. During testing, the fastest reset is PlayerPrefs.DeleteAll() from a temporary editor script or Edit > Clear All PlayerPrefs, which restores a fresh-install economy (Currency falls back to 0 and is seeded to initialMoney on first run). Be deliberate about this — clearing prefs also wipes unlocks, graphics settings (AudioVolume, MusicVolume, DrawDistance, Shadows, PP), and the ControllerType choice. The exact key list is documented in 14_APIReference.md.

Troubleshooting

Console warning: "Couldn't create a Convex Mesh … PaintableBody" — is this a problem?

No — this warning is benign and safe to ignore. The paintable body shells on the player and traffic prefabs (the meshes named PaintableBody) carry a convex MeshCollider, and Unity's PhysX backend caps a convex hull at 256 polygons. When the body mesh exceeds that cap, PhysX logs "Couldn't create a Convex Mesh" while still producing a usable simplified hull, so the car continues to collide correctly — head-on detection, side-swipe damage, and near-miss raycasts all keep working. You can silence it by reducing the collider mesh's poly count or swapping to primitive colliders, but it does not affect gameplay and ships in the stock project. The collision pipeline that matters runs in TO_Player.OnCollisionEnter(), which keys off the TO_TrafficCar layer and impulse, not the convex-hull warning.

Why does my car fight the AI / drift on the lane?

The on-car driver TO_OvertakeAI needs full input authority — it writes RCCP_Inputs every FixedUpdate and expects nothing else to push the car laterally. When the car hunts or drifts on the lane, something is competing with the AI: the legacy TO_PlayerStabilizer lane-centering assist, RCCP's own lane-following, or RCCP's low-speed auto-throttle. The asset resolves this through the externalControl flag: TO_Player.Stability() early-outs with if (CarController.externalControl) return;, so its sideways Rigidbody assist self-disables the moment the AI takes over, and RCCP's ApplyLaneFollowing() likewise early-outs under externalControl. If you imported a vehicle that still fights the AI, it is almost always because the RCCP setup is non-standard.

That is what TO_Player.CheckVehicleSetup() (editor-only) normalizes: it forces RCCP_CarController.ineffectiveBehavior = false, sets the Rigidbody damping to linearDamping = 0.01 / angularDamping = 0.35, disables the customizer's auto-save and auto-load, fixes the NOS torqueMultiplier to 3.5, clears applyBrakeOnDisable/applyHandBrakeOnDisable on the input, zeroes the clutch and matches its engage RPM to the engine, disables aero auto-reset, and sets each axle's maxBrakeTorque to 15000. Run this whenever a newly built car behaves oddly under the AI, then verify the car still drives cleanly in Play Mode.

My AI car won't accelerate / sits stuck at low speed and keeps resetting.

TO_Player has a deliberate low-speed reset: if the car stays at or below lowSpeedResetThreshold (10 km/h) continuously for lowSpeedResetDelay (3 seconds), ResetVehicle() repositions it on the path. The delay exists precisely so a brief slowdown — for example easing behind a slower lead car — does not trigger an instant reset; only a genuinely stuck car gets recovered. Separately, if the car drifts more than 100 units from the closest path point, it resets immediately. If your car resets constantly, check that the drivetrain produces torque (the RCCP engine/clutch/differential are wired) and that TO_CurvedRoadManager/TO_PathManager are present so a valid path point exists to reset onto.

When I play-test the player car alone, traffic keeps crashing into it. How do I isolate the car?

Disable the traffic container before play-testing the player car's handling or the AI. In the gameplay scene, deactivate the object that parents the spawned traffic (set the traffic container SetActive(false)) so no traffic cars are spawned, then you can evaluate cruise, lane-change smoothness, and stability without head-on collisions ending the run. This is the standard isolation step for any player-AI tuning pass — re-enable traffic only once the car drives the lane cleanly on its own. See 08_TrafficSystem.md for how traffic spawning and the container are organized.

A head-on with oncoming traffic ends the run instantly, but a side-swipe doesn't. Is that a bug?

That is by design — "the player owns the risk." In TO_Player.OnCollisionEnter(), a collision with an oncoming (left-lane) traffic car is classified by impact direction: the contact normal is flattened and dotted against the car's flattened forward axis, and if that frontal alignment is at or above headOnFrontalDot (0.5), the hit is a true head-on — damage jumps to 100, the explosion VFX spawns, and GameOver() fires immediately. A glancing side-swipe of the same oncoming car falls below the frontal cone and instead accrues survivable damage like an ordinary knock. Collisions only register at all when the impulse exceeds minimumCollisionForGameOver (4), filtering out trivial scrapes. Tune headOnFrontalDot (in the .asset) and minimumCollisionForGameOver to make crashes more or less forgiving.

See Also