I created a fish like object. I used “rigid body joints” to make its body sway when the head moves. I used the “hinge” pivot type. for some reason the “limits” settings don’t act like limits at all. they seem to make the joints more stiff but they don’t actually “limit” the angle. I tried setting the min and max values to 0, but the joints are still able to pivot, albeit less.
I have always used 6dof joints, ball and hinge have never worked right,
Just use a generic 6dof link and set min and max(from starting orientation)
Note: the pivot is the origin
Another thing you may need is a way to have it return to original position using forces or torque.
Limits are calculated with a slight delay to the forces acting on them. Thus there will always be some slop. You can try increasing physics substeps, or use an alternate way of joining them and restricting angles (by setting relative position and angle in some axis in python)