SceneKit 在动画开始时闪烁

SceneKit flashes at start of animation

我在使用 SceneKit 动画时有一个不明白的行为。 以下所有代码都在 renderer:updateAtTime: 委托调用的上下文中执行。

我是这样制作动画的:

         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 是不正确的做法,因为它会永远保留动画 "running"。

如何避免初始闪光?

您似乎设置了两次节点的旋转:一次是通过动画,一次是通过直接操作。他们互相干扰。

尝试完全删除 node.rotation = targetRotation

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

1 - renderer:updateAtTime:

(SceneKit 运行s 动画)

2 - renderer:didApply:AnimationsAtTime:

(...)

4 - renderer:willRenderSCne:atTime:

(SceneKit 渲染场景)

5 - renderer:didRenderScene:atTime:

现在,addAnimation:forKey 的文档:还说:"Newly added animations begin executing after the current run loop cycle ends"。

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

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