我在使用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并不是正确的做法,因为它会留下动画"运行"永远。
如何避免初始闪光?
答案 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)。没有闪光灯。