IsKinematic
enabled if you don't want it to act like a physics object.HingeJoint
does not constrain the absolute rotation
or localRotation
of the Transform that it is attached to. It constrains the relative rotation between its own RigidBody and the Rigidbody in the ConnectedBody
field.HingeJoint.angle
and HingJoint.axis
do not represent the rotation of the Transform that it is attached to. Ex:Quaternion.AngleAxis(hinge.angle, hinge.axis) // is *not* equivalent to either of hinge.transform.rotation hinge.transform.localRotation
To quote the official docs:
The rest angle between the bodies is always zero at the beginning of the simulation.
The consequence of this is that HingeJoint.angle
does not depend on the starting orientation of the joint's RigidBody
or the connected RigidBody
. And because HingeJoint.limits
represents limits on HingeJoint.angle
, the limits are also independent of any starting orientation of the bodies.
An example: Consider a GameObject
with rotation (0, 0, 0)
and a HingeJoint
on the x-axis with limits of [-90, 90]
. When played as-is, this GameObject
will be free to rotate between (-90, 0, 0)
and (90, 0, 0)
. However, if you rotate this GameObject
in the editor such that it starts with rotation (90, 0, 0)
and play it, the GameObject
will then be free to rotate between (0, 0, 0)
and (180, 0, 0)
- even though the angle limits have not changed.
In most cases, HingeJoint
should have a ConnectedBody
assigned. If left empty it causes your HingeJoint
to be anchored to the global physics coordinate system. If your HingeJoint
is the child of an object that moves, the joint will apply its limits within the global physics coordinate system - not in the joint's local coordinate system.
To ensure that your HingeJoint
behaves nicely, create a RigidBody
on the parent object and set that as the ConnectedBody
.1) In this configuration, the axis
and angle
of the HingeJoint
will correspond to the localRotation
of the Transform
2). This makes the joint behavior much easier to reason about!