Search code examples
swiftsprite-kitskphysicsbody

How to rotate a SKPhysicsBody like a wheel


My goal is to rotate a circular node like a wheel driven by a motor, e.g. when rotating clockwise the wheel will move right due to friction of the floor.

According to other threads the way to rotate a SKPhysicsBody is to rotate the body it is attached to.

This code rotates the sprite but not the physicsbody. How do I solve this problem?

let circle = SKSpriteNode(imageNamed: ”circle")
circle.position = CGPoint(x: size.width * 0.5, y: size.height * 0.9)
circle.physicsBody = SKPhysicsBody(circleOfRadius: circle.frame.width/2)
if let physics = circle.physicsBody {
    physics.affectedByGravity = true
    physics.allowsRotation = true
    physics.restitution = 0.2
    physics.friction = 1.0
    physics.isDynamic = true;
    physics.mass = 10
}
addChild(circle)
let rotateAction = SKAction.rotate(byAngle: .pi, duration: 1.0)
let repeatAction = SKAction.repeatForever(rotateAction)
circle.run(repeatAction)

PS. This way of creating the body is not working in iOS 13 but should not affect the outcome.

circle.physicsBody = SKPhysicsBody(texture: SKTexture(imageNamed: ”circle"), size: circle.size)

Solution

  • While moving or rotating a sprite directly will move the physics body too, the physics engine is there to move the sprites for you so that you don't have to worry about it. The philosophy is to let it do the work rather than to add actions for creating the movements directly.

    If you want a sprite with an attached body to rotate, either apply an angular impulse to the body (as suggested by Knight0fDragon) or just set the physics body's angularVelocity directly. You might also want to set angularDamping to 0 if you don't want the rotation to stop. E.g.,

    ...
    addChild(circle)
    circle.physicsBody?.angularDamping = 0
    circle.physicsBody?.angularVelocity = .pi
    ...
    

    Then remove the circle.run(...) and see what happens.