I currently have a ragdoll figure, which consists of a parent node (with no physics bodies attached), and lots of child nodes which each consist of a circle body. The circles are connected to each other using an SKPhysicsJointPin
between each circle, as so:
Each SKPhysicsJointPin
has shouldEnableLimits = true
, and I currently use a value of -0.05 and 0.05 for lowerAngleLimit
and upperAngleLimit
respectively.
This works pretty well and prevents the shape from deforming too much, except when the figure goes upside-down as a whole, in which case all the joints suddenly try to contract, like so:
- See also: Video
The joints contract very quickly about when the figure is completely upside down. When he rotates back again, all the joints return to normal. Why does this happen? How do I maintain the correct angles on the joints?
Edit 1:
I just tried rewriting the project in Objective-C in case it was due to some weird Swift bug; turns out this problem still manifests itself in Objective-C, so I've removed the Swift tag.
My best guess at the moment is that the angle of the joints, relative to the world, are incorrectly calculated by SpriteKit when the bodies they are attached to are rotated more than 180° in either direction, and so wrong angles are being passed to the underlying Box2D joints.
I wasn't sure if I was supposed to continuously update the lower- and upper-angle limits to match their bodies' world angles, but it doesn't seem I have to as when the body is very close to being upside-down do the joints stop working properly. I'm going to keep experimenting, anyway…
Edit 2:
I'm now fairly sure that the problem occurs because SpriteKit is (I guess with good reason) modifying the zRotation
value to keep it between -180° and 180°. If for example the node is rotating clockwise and it hits -180°, SpriteKit automatically wraps its value back to +180°. I'm fairly confident this wrap-around is causing the joints to behave erratically, I just need to figure out how to counteract it…
Edit 3:
I've uploaded the sample application (including video) which demonstrates this problem, as originally asked for by Apple: Xcode Project / Video