2017-11-28 16 views
0

ARSession에서 주기적으로 노드를 애니메이션 할 때 문제가 있습니다. 5 초마다 인터넷에서 데이터를 가져오고이 데이터를 사용하여이 노드를 업데이트합니다 (축소 또는 확대). 내 코드는 다음과 같이 보입니다 :ARKit에서 SCNNode를 애니메이션하기위한 디스패치 큐

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 by resource constraints [1] 업데이트가 제대로 발생하지만, 5 초마다 나는이 "짧은 정지"를 얻을 경우 UX 정말 clumpsy입니다

내가 너무 동시 큐를 만드는 시도했다 : let animationQueue = DispatchQueue(label: "animationQueue", attributes: DispatchQueue.Attributes.concurrent) 을 대신 주요 한때의 animationQueue.async 전화 그러나 문제는 지속됩니다. 나는 어떤 제안든지 감사 할 것입니다.

편집이 : 거기에 하위 노드의 각 update 방법은 현장에 대한 업데이트가 SCNTransaction를 사용하려면이

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") 

답변

0

모양이다, 그것은 모든 변경 사항은 해당 스레드에서 만들어진 확인합니다.

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() } 
    } 
} 
+0

제안에 감사드립니다. @ Lësha Turkowski. 문제는 각 node1, node2, node3의 업데이트 메소드에 있습니다. CAAnimation을 사용하여 노드에 추가하고 있습니다. SCNTransaction 접근법은 올바르게 이해할 수 있다면 노드의 애니메이션 속성을 설정하는 것만으로도 작동할까요? – leandrodemarco

+0

@leandrodemarco 'SCNTransaction'은 장면을 원자 적으로 변경하는 데 사용됩니다. (예를 들어, Apple이 그것을 사용하여 샘플 게임에서 부모로부터 노드를 제거하는 등) 애니메이션 속성을 사용하여 아무 것도 할 필요가 없습니다. 나는 CAAnimation과 함께 사용하지는 않았지만 왜 작동하지 않는지는 알 수 없다. –