Can't change SKPhysicsJointLimit maxLength aft

2019-06-28 05:07发布

问题:

So, I've created a ring of SKSpriteNodes which are essentially rectangles that are joined together using pin joints. I'd like to suspend this ring inside of an SKShapeNode circle. I have connected each of the nodes to the SKShapeNode using SKPhysicsJointLimit's.

This all works fine, and I get the effect that I'm looking for if I set the maxLength to the "right" number, which I determine subjectively.

I've stored all of the limit joints inside of an Array, so I can get easy access, and I've added them to the physicsWorld.

All of this works properly and as expected, though it took a little work to get the code right. These things are picky!

Now, what I'd really like to do is set the maxLength equal to some large number and then gradually reduce that number over time so that the ring goes from "hanging loosely" to "pulled taut"

I've tried a variety of approaches -- none of which seem to work. First, I tried:

SKAction *tighten = [SKAction customActionWithDuration:1 actionBlock:^(SKNode *node, CGFloat elapsedTime) {
    CGFloat t = elapsedTime/duration;
    CGFloat p = t*t;
    CGFloat newLimit = fromLimit*(1-p) + toLimit*p;
    for (int i = 0; i < _connectors.count; i++){
        [[_connectors objectAtIndex:i] setMaxLength:newLimit];
    }
}];

[_ring runAction:tighten];

but this simply didn't do anything at all.

I finally realized that you don't appear to be able to change the properties of a joint after it has been added to the physicsWorld. So, I tried something like this in the update method of the scene:

        [scene.physicsWorld removeJoint:[_connectors objectAtIndex:i]];
        [[_connectors objectAtIndex:i] setMaxLength:newLimit];
        [scene.physicsWorld addJoint:[_connectors objectAtIndex:i]];

but, this didn't work either. It threw the error:

'Cant add joint <PKPhysicsJointRope: 0x114e84350>, already exists in a world'

even though I've clearly removed it. So, I don't really know where to go from here. The documentation on joints and the existing material on the internet is very thin. I suppose the next thing I would try is removing all joints and et-adding them, but that's going to be a huge pain.

Any thoughts would be really quite helpful!

回答1:

As noted by OP it appears the joint must be removed from physics world before the change applies. The below worked for me.

for joint in joints
{
    physicsWorld.removeJoint(joint)
    joint.maxLength = yourNewValue
    physicsWorld.addJoint(joint)
}