SceneKit动画播放后停留在最后帧及反向动画问题求助
解决SceneKit动画播放后复位、反向动画无效问题
核心修改点
要实现动画停留在最后帧、支持反向播放且可重复执行,需调整以下关键属性:
- 设置
animation.isRemovedOnCompletion = false:避免动画完成后被自动移除 - 设置
animation.fillMode = .forwards:让节点保持动画最后一帧的状态 - 避免动画播放器状态丢失,确保每次播放时正确控制进度
- 修复代码中变量名冲突问题(循环内的
animation与参数重名)
修改后的正向播放代码
private func playAnimation(with targetAnimation: ARAnimation) { for object in virtualObjectLoader.loadedObjects { guard object.hash == targetAnimation.objectSystemHash else { continue } object.enumerateChildNodes { (child, stop) in guard !child.animationKeys.isEmpty else { return } for key in targetAnimation.animationKeys { guard let animationPlayer = child.animationPlayer(forKey: key) else { continue } // 重置播放器状态,确保从起始位置播放 animationPlayer.stop() animationPlayer.currentTime = 0 // 配置动画属性 let animation = animationPlayer.animation animation.repeatCount = 0 animation.isRemovedOnCompletion = false animation.fillMode = .forwards // 正向播放 animationPlayer.speed = 1 animationPlayer.play() } } } reserveAnimationButton.isHidden = false playedAnimation = targetAnimation }
修改后的反向播放代码
private func reverseAnimation() { guard let targetAnimation = playedAnimation else { return } for object in virtualObjectLoader.loadedObjects { guard object.hash == targetAnimation.objectSystemHash else { continue } object.enumerateChildNodes { (child, stop) in guard !child.animationKeys.isEmpty else { return } for key in targetAnimation.animationKeys { guard let animationPlayer = child.animationPlayer(forKey: key) else { continue } // 确保动画停留在当前帧,配置反向播放属性 let animation = animationPlayer.animation animation.isRemovedOnCompletion = false animation.fillMode = .forwards // 反向播放:如果当前已在起始位置,先跳转到结束位置 if animationPlayer.currentTime <= 0 { animationPlayer.currentTime = animation.duration } animationPlayer.speed = -1 animationPlayer.play() } } } reserveAnimationButton.isHidden = true }
关键修改说明
- 变量名冲突修复:将参数
animation改为targetAnimation,避免与循环内的动画变量重名,防止逻辑混乱。 - 动画保留与状态保持:正反向播放时都设置
isRemovedOnCompletion = false和fillMode = .forwards,确保动画完成后节点不会回到初始状态。 - 正向播放重置:每次正向播放前停止播放器并重置
currentTime到0,保证每次都从动画开头播放。 - 反向播放处理:检查播放器当前时间,若已在起始位置则将
currentTime设为动画总时长,确保反向播放从最后一帧回到起始帧;设置speed = -1实现反向播放。 - 效率优化:遍历对象时先判断
hash是否匹配,减少不必要的节点遍历。
修改后,动画播放完成会停留在最后帧,反向动画可正常从最后帧回到初始帧,且整个流程可重复执行(正向→反向→正向循环),动画不会被移除。
内容的提问来源于stack exchange,提问作者martin wotterman
相关产品推荐
相关产品推荐

