# 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