# 6. Character Controller Pitfalls
Part of [[Character Controllers]]. Previous: [[5. Gray-Box Metrics Gym]]. See also [[7. Physics Pitfalls]] and [[6. Physics 2D Pitfalls and LowLevelPhysics2D]].
> [!note] Verification status
> `enableOverlapRecovery`, `minMoveDistance`, `skinWidth` and `velocity` are listed on the 6000.5 `CharacterController` reference. The teleport row in 6.1 is long-standing community knowledge (CharacterController keeps its own internal position), **not** a sentence I found in the 6000.5 docs - verify in your version. **Code not compiled.**
## 6.1 CharacterController
| Symptom | Cause | Fix |
|---|---|---|
| `isGrounded` flickers walking downhill | `isGrounded` only reflects the last `Move`; no downward motion = no ground contact | Always include a small negative Y while grounded (Part 3 uses -2 m/s) |
| Footsteps/coyote fire randomly | same flicker | Fix the above; or grounded = `CollisionFlags.Below` OR short SphereCast |
| Character snaps/pops up small edges | `stepOffset` too high | Match `stepHeight` in metrics; keep < height |
| Stuck on edges / jitter in corners | `skinWidth` too small | ~10% of radius (Manual guideline) |
| Hovering above ground | `skinWidth` too large, or `center` wrong | Lower skin; pivot at feet with `center.y = height/2` |
| Can walk up steep ramps by hopping | slope limit applies to walking, not jumping | Add steep-slope slide (Part 3) |
| `transform.position = x` doesn't teleport, or snaps back | controller's internal position overrides it | `cc.enabled = false; transform.position = x; cc.enabled = true;` (verify, see note) |
| Movement ignored when tiny | `minMoveDistance` > 0 | Leave at 0 (Manual default advice) |
| Two scripts call `Move` | double speed, double callbacks | One "motor" owns `Move`; other systems feed it velocities (Component pattern, [[Game Programming Patterns (Review)]]) |
| Not hitting triggers / not pushed by physics | CC isn't a Rigidbody | Triggers work (CC is a Collider); pushes must be applied manually |
| Character stuck after spawn inside geometry | overlap | `enableOverlapRecovery` (depenetrates from static objects; check its default in your version) or spawn above ground |
## 6.2 Rigidbody characters
| Symptom | Cause | Fix |
|---|---|---|
| Sticks to walls mid-air | wall friction | Zero-friction material with **Minimum** combine |
| Slides down gentle ramps when idle | gravity component along slope | Cancel into-surface velocity, project movement on plane (Part 4) |
| Launches off ramp crests | horizontal velocity kept at crest | Project desired velocity on ground normal; snap-to-ground probe |
| Camera jitter | camera in Update, body in FixedUpdate without interpolation | `Interpolate` on the Rigidbody; Cinemachine follows the interpolated transform |
| Jump height varies | forces applied in Update / variable dt; or platforms adding velocity | Set `linearVelocity.y` directly for jumps, in FixedUpdate |
| Passes through thin walls when dashing | discrete detection | `ContinuousSpeculative` or `ContinuousDynamic` |
| Pushed around by light props | mass ratio | Raise player mass or put props on a layer that only collides via kinematic proxy |
## 6.3 Both
- **Scale:** never scale the player root non-uniformly. Capsule metrics assume 1 unit = 1 m.
- **Metric drift:** someone tweaks `runSpeed` to make one level work - every other level breaks. Lock the metrics asset, version it ([[Version Control]]), and re-run the gym (Part 5) after any change.
- **Moving platforms in FixedUpdate + CC in Update:** carry delta arrives in 50 Hz steps -> stutter. Interpolate platforms, or move platforms in Update when the rider is a CC.
- **Animation vs controller speed mismatch:** feet slide. Drive blend-tree speed from actual `velocity` magnitude, not input ([[3.Blend Trees]]).
- **VR:** in a Quest rig the HMD moves the camera independently of the body; the capsule must follow the head XZ each frame. Use the XR locomotion stack (Unity 6.3 LTS for Quest 2 per [[0.Choosing a Unity Version]]) rather than these controllers directly; keep the metrics for doors/ledges ([[7.Quest 2 Worked Example Room]]).
- **Networking:** a CC is easier to predict and reconcile; see [[Multiplayer with Netcode for GameObjects]] before syncing a Rigidbody player.
## Docs
- `CharacterController`: https://docs.unity3d.com/6000.5/Documentation/ScriptReference/CharacterController.html
- Character Controller component: https://docs.unity.com/en-us/engine/6000.5/manual/physics-section/physics-overview/character-control-section/class-character-controller
- Collision detection modes: https://docs.unity3d.com/6000.5/Documentation/Manual/physics-optimization-cpu-rigidbody-collision-modes.html