我在尝试定期为 ARSession 上的节点设置动画时遇到问题。我每 5 秒从 Internet 获取数据,然后使用该数据更新此节点(缩小或放大)。 我的代码看起来像这样:
Timer.scheduledTimer(withTimeInterval: 5, repeats: true) { timer in
fetchDataFromServer() {
let fetchedData = $0
DispatchQueue.main.async {
node1.update(fetchedData)
node2.update(fetchedData)
node3.update(fetchedData)
}
if stopCondition { timer.invalidate() }
}
}
问题是在调用更新时我看到了一个小故障,在这个小故障中相机似乎卡住了几分之一秒并且我在控制台中看到以下消息:[Technique] World tracking performance is being affected受资源限制 [1]
更新正确发生,但如果每 5 秒我得到这些“短暂卡住”,用户体验真的很笨拙
我也试过创建并发队列:
让 animationQueue = DispatchQueue(标签:“animationQueue”,属性:DispatchQueue.Attributes.concurrent)
并调用 animationQueue.async
而不是主队列,但问题仍然存在。
如果有任何建议,我将不胜感激。
编辑:update
方法中的每个子节点如下所示
private func growingGeometryAnimation(newHeight height: Float) -> CAAnimation{
// Change height
let grow = CABasicAnimation(keyPath: "geometry.height")
grow.toValue = height
grow.fromValue = prevValue
// .... and the position
let move = CABasicAnimation(keyPath: "position.y")
let newPosition = getNewPosition(height: height)
move.toValue = newPosition.y + (yOffset ?? 0)
let growGroup = CAAnimationGroup()
growGroup.animations = [grow, move]
growGroup.duration = 0.5
growGroup.beginTime = CACurrentMediaTime()
growGroup.timingFunction = CAMediaTimingFunction(
name: kCAMediaTimingFunctionEaseInEaseOut)
growGroup.fillMode = kCAFillModeForwards
growGroup.isRemovedOnCompletion = false
growGroup.delegate = self
return growGroup
}
self.addAnimation(growingGeometryAnimation(newHeight: self.value), forKey: "bar_grow_animation")
最佳答案
要对场景进行任何更新,请使用 SCNTransaction
,它确保所有更改都在适当的线程上进行。
Timer.scheduledTimer(withTimeInterval: 5, repeats: true) { timer in
fetchDataFromServer() {
let fetchedData = $0
SCNTransaction.begin()
node1.update(fetchedData)
node2.update(fetchedData)
node3.update(fetchedData)
SCNTransaction.commit()
if stopCondition { timer.invalidate() }
}
}
关于swift - 调度队列以在 ARKit 中为 SCNNode 设置动画,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47522995/