Arti
Arti

Reputation: 7772

SceneKit SCNAction.run and rotation not working

I have a scene with a box that should run a rotation action forever:

dps is a property that could be changed by user.

override func viewDidAppear() {
        super.viewDidAppear()

        let scene = SCNScene()
        scene.rootNode.addChildNode(boxNode)
        self.rateScene.scene = scene

        let actionwait = SCNAction.wait(duration: 0.001)
        let run = SCNAction.run {_ in
            let fps = 60.0
            let delta = (self.dps*3.14/180.0)/fps
            self.boxNode.rotation.z -= CGFloat(delta)
        }
        let moveSequence = SCNAction.sequence([actionwait, run])
        let forever = SCNAction.repeatForever(moveSequence)
        boxNode.runAction(forever)

    }

Variable self.boxNode.rotation.z - changes every time, but the box doesn't rotate.

Upvotes: 2

Views: 2125

Answers (2)

Hal Mueller
Hal Mueller

Reputation: 7665

How about keeping a DPS property on the scene or scene's owner, and use a didSet on the DPS? The didSet will reset the rotation, something like:

let radiansPerSecond = M_PI / 180.0 * dps
let rotate = SCNAction.repeatForever(SCNAction.rotateBy(x: 0.0, y: 0, z: radiansPerSecond, duration: 1.0))
boxNode.runAction(rotate)

The DPS change can be caught within 1 second and your action gets restarted with the new rotation rate. And you don't have to set a new SCNAction 60 times per second.

Upvotes: 1

NFC.cool
NFC.cool

Reputation: 3312

This wont work because the SCNAction.run is just evaluated once. You have to reassign the action every time you change the value.

What you could do is something like that. Simply put that code in the IBAction of your slider (or whatever the user uses to control the value)

let fps = 60.0
let delta = (self.dps * 3.14 / 180.0) / fps

SCNTransaction.begin()
SCNTransaction.animationDuration = 0.1
boxNode.rotation.z -= Float(delta)
SCNTransaction.commit()

Upvotes: 5

Related Questions