【发布时间】:2018-05-19 03:46:53
【问题描述】:
我正在创建一个应用程序,其中我在 AR 应用程序中使用 SceneKit 内容。我有多个节点,它们被放置在场景中的不同位置。它们可能在也可能不一定在一个父节点内。用户必须根据应用程序设置的挑战选择正确的节点。如果用户选择了正确的节点,则正确的节点会播放一种动画,而错误的节点(可能是几种)会播放另一组动画。我正在直接使用 CAAnimation 完成动画,这一切都很好。基本上为了实现这一点,我正在创建一个所有节点的数组并将它们用于动画。
DispatchQueue.global(qos: .userInteractive).async { [weak self] in
for node in (self?.nodesAddedInScene.keys)! {
for index in 1...node.childNodes.count - 1 {
if node.childNodes[index].childNodes.first?.name == "target" {
self?.riseUpSpinAndFadeAnimation(on: node.childNodes[index])
} else {
self?.fadeAnimation(on: node.childNodes[index])
}
}
}
}
当用户选择“目标”节点时,该节点会播放一组动画,而其他节点会播放另一组动画。
RiseUpSpinAndFadeAnimation:
private func riseUpSpinAndFadeAnimation(on shape: SCNNode) {
let riseUpAnimation = CABasicAnimation(keyPath: "position")
riseUpAnimation.fromValue = SCNVector3(shape.position.x, shape.position.y, shape.position.z)
riseUpAnimation.toValue = SCNVector3(shape.position.x, shape.position.y + 0.5, shape.position.z)
let spinAnimation = CABasicAnimation(keyPath: "eulerAngles.y")
spinAnimation.toValue = shape.eulerAngles.y + 180.0
spinAnimation.autoreverses = true
let fadeAnimation = CABasicAnimation(keyPath: "opacity")
fadeAnimation.toValue = 0.0
let riseUpSpinAndFadeAnimation = CAAnimationGroup()
riseUpSpinAndFadeAnimation.animations = [riseUpAnimation, fadeAnimation, spinAnimation]
riseUpSpinAndFadeAnimation.duration = 1.0
riseUpSpinAndFadeAnimation.fillMode = kCAFillModeForwards
riseUpSpinAndFadeAnimation.isRemovedOnCompletion = false
shape.addAnimation(riseUpSpinAndFadeAnimation, forKey: "riseUpSpinAndFade")
}
FadeAnimation:
private func fadeAnimation(on shape: SCNNode) {
let fadeAnimation = CABasicAnimation(keyPath: "opacity")
fadeAnimation.toValue = 0.0
fadeAnimation.duration = 0.5
fadeAnimation.fillMode = kCAFillModeForwards
fadeAnimation.isRemovedOnCompletion = false
shape.addAnimation(fadeAnimation, forKey: "fade")
}
我希望动画能够奏效,实际上是这样。但是,问题在于节点位于数组中,所有节点的动画并不是同时完成的。动画开始时存在细微差别,这实际上导致 UI 不太好。
我正在寻找的是一种逻辑,其中我可以在所有节点上附加动画,然后当假设用户点击正确的节点时一起调用这些动画。数组对我来说似乎不是一个明智的选择。但是,我担心如果我将所有这些节点都设为空节点的子节点并在该空节点上运行动画,则可能首先很难管理这些子节点的放置,因为它们应该保持在随机距离,不一定靠得很近。鉴于这最终推动了 AR 体验,它变得更加糟糕。
请求一些输入是否有方法可以将动画附加到多个(从这些对象中选择的)对象(即使是按顺序)但同时运行它们。我使用了shape.addAnimation(fadeAnimation, forKey: "fade")“forKey”,可以在这种用例中使用吗?任何指针表示赞赏。
【问题讨论】:
标签: ios swift scenekit arkit caanimation