Reputation: 28912
I want to animate 2 cubes forever, until the user taps one of it. The animation is supposed to be like an ∞.
These are my cubes in the sceneView I want to animate:
I am trying to do that with nested animations and it does partially work. Now, since the animations always wait until they're finished before starting the new one, it does not look smooth at all.
Before continuing to develop the ∞-animation I would like to know if there is a better (and actually working) way. This is my current code:
SCNTransaction.begin()
SCNTransaction.setAnimationDuration(2)
cube1.position = SCNVector3Make(3, 0, 0)
cube2.position = SCNVector3Make(-3, 0, 0)
println("log 0")
SCNTransaction.setCompletionBlock {
println("log 1")
while (animationKey != 1) {
//initially animationKey = 0
SCNTransaction.begin()
SCNTransaction.setAnimationDuration(2)
cube1.position.x += 1
cube1.position.y += 1
cube2.position.x += 1
cube2.position.y += 1
println("log 2")
SCNTransaction.setCompletionBlock {
SCNTransaction.begin()
SCNTransaction.setAnimationDuration(2)
cube1.position.x -= 1
cube1.position.y -= 1
cube2.position.x -= 1
cube2.position.y -= 1
println("log 3")
SCNTransaction.setCompletionBlock { animationKey = 1 }
SCNTransaction.commit()
}
println("log 4")
SCNTransaction.commit()
}
}
println("log 5")
SCNTransaction.commit()
println("log 6")
}
The output shows the following things:
log 0, log 5, log 6, log 1, log 2, log 4, log 2
...and then it just continues with log 4
and log 2
alternating.
Can someone help me there?
Note
I thought a recursive approach would be better, I therefore replaced animationKey = 1
with calling the method this is in...didn't work at all anymore.
I got the animations to work once but now it just stops after finishing the very first animation and totally ignores the 2nd and 3rd animation block...
Upvotes: 13
Views: 10149
Reputation: 1264
If you're going to animate a SCNNode
have your nodes run a SCNAction
.
Swift:
let moveUp = SCNAction.moveBy(x: 0, y: 1, z: 0, duration: 1)
moveUp.timingMode = .easeInEaseOut;
let moveDown = SCNAction.moveBy(x: 0, y: -1, z: 0, duration: 1)
moveDown.timingMode = .easeInEaseOut;
let moveSequence = SCNAction.sequence([moveUp,moveDown])
let moveLoop = SCNAction.repeatForever(moveSequence)
myNode.runAction(moveLoop)
Objective-C:
SCNAction *moveUp = [SCNAction moveByX:0 Y:1 Z:0 duration:1];
moveUp.timingMode = SCNActionTimingModeEaseInEaseOut;
SCNAction *moveDown = [SCNAction moveByX:0 Y:-1 Z:0 duration:1];
moveDown.timingMode = SCNActionTimingModeEaseInEaseOut;
SCNAction *moveSequence = [SCNAction sequence:@[moveUp,moveDown]];
SCNAction *moveLoop = [SCNAction repeatActionForever:moveSequence];
[myNode runAction:moveLoop];
The code above will animate myNode
up and down forever.
Upvotes: 37
Reputation: 13462
you can create a CAKeyframeAnimation
animation from a Bezier path (see the path
property). That way you will get a very smooth animation.
For it to repeat forever set its repeatCount
to HUGE_VALF
, and you can adjust the velocity using the timingFunction
property.
Upvotes: 4