Been rebuilding my third-person character controller from scratch, not for the first time or even the second, and this time I committed to fully animation-driven movement. No RigidBody3D, just CharacterBody3D with move_and_slide() and manually computed velocity every frame.
It genuinely handles better. My last version used an actual rigidbody and I spent more time fighting the physics engine than building game feel. Overshooting on slopes, weird rotational torque on collision, linear damping that never quite worked. Adding a wall jump meant counteracting physics forces I hadn't asked for in the first place.
Going animation-driven flipped everything. Acceleration curves are explicit. Air control is a tunable float, not an emergent property of forces I don't fully control. Landing squash is just a tween on local scale. The whole thing is predictable, which turns out to matter a lot more than I expected.
Now I'm adding a water swimming state and I'm starting to second-guess some decisions. Buoyancy without a physics body is surprisingly awkward. I'm computing a target velocity and lerping toward it based on submersion depth, with extra damping applied on all axes. It sort of works, but the edge cases keep multiplying and it's feeling increasingly like a house of cards.
I'm wondering if the right move is a proper hybrid: animation-driven for ground and air, hand off to actual physics for water, ragdoll, and vehicles, then reclaim control on exit. But managing velocity continuity across the handoff seems like it could get messy fast, especially if the player transitions mid-movement.
Has anyone shipped something with a hybrid control mode like this? How do you keep the handoff clean? Or do you just fake everything and accept that your action game's water physics is going to be, at best, vibes-based?