SceneKit在动画开始时闪烁

时间:2017-05-21 16:44:55

标签: macos animation scenekit

我在使用SceneKit动画时有一些我不明白的行为。 以下所有代码都在渲染器的上下文中执行:updateAtTime:delegate call。

我像这样构建我的动画:

         SCNVector4 startRotation   = node.rotation ;
         SCNVector4 targetRotation  = pose.rotation ;

         CABasicAnimation    *rotAnimation   = [CABasicAnimation animationWithKeyPath:@"rotation"] ;
         rotAnimation.fromValue  = [NSValue valueWithSCNVector4:startRotation] ;
         rotAnimation.toValue    = [NSValue valueWithSCNVector4:targetRotation] ;
         rotAnimation.duration   = duration ;

现在,如果我之后立即执行此操作:

         // First change the final rotation state, and then start the animation
         node.rotation  = targetRotation ;
         [node addAnimation:rotAnimation forKey:animationName] ;

我在最终位置快速闪现角色,然后动画从startRotation运行到targetRotation并永远保持在targetRotation位置 - 这就是我想要的,除了闪光灯。

如果我这样做(只需交换最后两行的顺序):

         // First start the animation and then set the final position
         [node addAnimation:rotAnimation forKey:animationName] ;
         node.rotation  = targetRotation ;

我没有闪光灯,但是当动画结束时,角色会回到初始位置,这不是我想要的。

我读到了关于fillMode和removedOnCompletion的内容,但是将removedOnCompletion设置为NO并不是正确的做法,因为它会留下动画"运行"永远。

如何避免初始闪光?

2 个答案:

答案 0 :(得分:0)

看起来你正在设置节点的旋转两次:一次是动画,一次是直接操作。他们互相干扰。

尝试完全删除node.rotation = targetRotation

答案 1 :(得分:0)

所以这是故事。正如Apple在其文档中所述,SceneKit呈现在循环中发生,并且按以下顺序调用了几个委托方法:

1 - 渲染器:updateAtTime:

(SceneKit运行动画)

2 - 渲染器:didApply:AnimationsAtTime:

(...)

4 - 渲染器:willRenderSCne:atTime:

SceneKit渲染场景

5 - 渲染器:didRenderScene:atTime:

现在,addAnimation的文档:forKey:也说:"新添加的动画在当前运行循环周期结束后开始执行 "。

我跟踪了节点及其表示节点的旋转值。当我在渲染器中添加动画时:updateAtTime :(步骤1),我首先设置节点目标位置,然后添加动画,但此动画不会在当前运行循环结束之前执行。所以SceneKit渲染这个最终位置(在步骤4和5之间),然后,在下一个周期,SceneKit将运行动画(在步骤1和2之间),并且presentationNode获得正确的值并在步骤4和5之间再次渲染 - 闪光灯。

相反,如果我在渲染器中添加动画:didRenderScene:atTime :(步骤5),循环结束,动画被调度并在SceneKit到达渲染时间之前运行(在步骤1和2之间)(步骤之间) 4和5)。没有闪光灯。