Phase 3 updates

Phase 3 · Slice 4 ·

Joints and CharacterController

  • CharacterController on PhysX's capsule controller, as Unity's:
    • Move with collide-and-slide, stepOffset, slopeLimit, skinWidth and minMoveDistance.
    • CollisionFlags (not a [Flags] enum, as in Unity), isGrounded and velocity.
    • SimpleMove: gravity accumulates, and horizontal speed applies only while grounded (recorded).
    • OnControllerColliderHit carries PhysX's per-pass direction and length, through a hand-built vtable for PxUserControllerHitReport.
    • The controller is a collider for triggers and queries. Move doesn't sync transforms; script teleports are overwritten.
    • character_controller: 220 checks.
  • 3D joints (PhysX):
    • FixedJoint, SpringJoint (distance joint) and HingeJoint (D6: twist motor, limits, spring).
    • ConfigurableJoint (D6 motions, linear/twist/swing limits, drives) and CharacterJoint.
    • Breaking, with OnJointBreak, and currentForce/currentTorque.
    • Unity's conventions: actor 0 is the connected body; angles from the start pose; auto connected anchors computed when configured.
    • joints_basic: 197 checks.
  • 2D joints (Box2D): HingeJoint2D, DistanceJoint2D (rod and rope), SpringJoint2D, FixedJoint2D, SliderJoint2D, WheelJoint2D, TargetJoint2D.
    • Breaking by reaction force, as Unity does, with OnJointBreak2D and breakAction.
    • Unity's per-type auto-anchor defaults, including the wheel's connected-body origin.
    • Box2D 2.3's prismatic limit slop.
    • joints2d_basic: 229 checks.
  • Scenes: Unity's settings structs (JointSpring, JointLimits, JointMotor2D...) as JSON objects; Infinity and NaN floats as strings.
  • Sample: joints_playground.json, played by an MCP e2e test: the controller pushes a crate, crosses the hinged bridge and opens the door.
  • Next: AudioSource, SceneManager and PlayerPrefs (done in slice 5).