How to properly scale parent/child nodes with physics bodies and joints.

I have a character in a spritekit scene that I'd like to scale when he receives a certain power up.


Simple example where I might scale up/down:


hero.run (SKAction.repeatForever(
    SKAction.sequence([
        SKAction.scale(to: 1.5, duration: 1),
        SKAction.scale(to: 1, duration: 1)
        ])
))


Easy enough so far. The problem is the scaling looks terrible because the hero has body parts that are affixed with joints. It appears to me the physics nodes for the parts scale properly but the joints don't.


Here is an example swift playground that illustrates the problem. It simply adds some color nodes in the rough shape of a car. I've added joints to the front wheel and bumper but not the rear wheel.


import SpriteKit
import PlaygroundSupport
let sceneView = SKView(frame: CGRect(x: 0, y: 0, width: 640,
                                     height: 480))
let scene = SKScene(size: CGSize(width: 160, height: 120))
sceneView.showsFPS = true
sceneView.showsPhysics = true
sceneView.presentScene(scene)
PlaygroundPage.current.needsIndefiniteExecution = true
PlaygroundPage.current.liveView = sceneView
scene.physicsWorld.gravity = CGVector(dx:0,dy:0)
let body = SKSpriteNode(color: UIColor.red, size: CGSize(width:70,height:15))
body.position = CGPoint(x:scene.size.width/2,y:scene.size.height/2)
scene.addChild(body)

let front = SKSpriteNode(color:UIColor.blue, size: CGSize(width:10,height:10))
front.position = CGPoint(x:-25,y:-12.5)
body.addChild(front)

let rear = SKSpriteNode(color:UIColor.blue, size: CGSize(width:10,height:10))
rear.position = CGPoint(x:25,y:-12.5)
body.addChild(rear)

let bumper = SKSpriteNode(color:UIColor.brown, size: CGSize(width:5,height:5))
bumper.anchorPoint = CGPoint(x:0,y:0)
bumper.position = CGPoint(x:35,y:-7.5)
body.addChild(bumper)

body.physicsBody = SKPhysicsBody(rectangleOf:body.size)
front.physicsBody = SKPhysicsBody(rectangleOf:front.size)
bumper.physicsBody = SKPhysicsBody(rectangleOf:bumper.size, center:CGPoint(x:2.5,y:2.5))
let axel = SKPhysicsJointPin.joint(withBodyA:body.physicsBody!, bodyB:front.physicsBody!, anchor: body.convert(front.position, to: scene))
scene.physicsWorld.add(axel)
let bodyJoint = SKPhysicsJointFixed.joint(withBodyA: body.physicsBody!, bodyB: bumper.physicsBody!, anchor: body.convert(bumper.position, to:scene))
scene.physicsWorld.add(bodyJoint)
body.run (SKAction.repeatForever(
    SKAction.sequence([
        SKAction.scale(to: 1.5, duration: 3),
        SKAction.scale(to: 1, duration: 3)
        ])
))



You can see that all the nodes are properly scaled. Only the rear wheel without a joint maintains it's correct position in the car though. The bumper and front wheel joint positions don't change size with the node scaling therefore when the nodes get larger they distort the shape of the composite.


Anyone have a way around this? I've been experimenting with different solutions like maybe adding hidden child nodes or other such hacks/workarounds but nothing is really sticking. The best I've got so far is that if you change the anchorPoint of two nodes to match where you want the joints to occur and then put the joint exactly on the anchor, you can then scale the nodes and have the proper effect because nodes scale around their respective anchor points. The problem is this only works when there is only one joint per node. In the case above, where there are two wheels for instance, there isn't much I can think of to do.