簡體   English   中英

同時在多個SceneKit節點上進行CAAnimation

[英]CAAnimation on multiple SceneKit nodes simultaneously

我正在創建一個應用程序,其中我在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”,可以在這種用例中使用嗎? 任何指針贊賞。

通過使用暫停(.speed = 0)的CAKeyframe動畫並在SCNSceneRendererDelegate“renderer(updateAtTime :)”函數內設置動畫的時間偏移(.timeOffset),我已經有多達50個SCNNodes動畫完美和諧。

令人驚訝的是,如何為大量節點添加每1/60秒的時間偏移的暫停動畫。 向SceneKit開發人員致敬,因為他們在添加和刪除CAAnimations方面的開銷很小。

在解決這個問題之前,我嘗試了許多不同的CAAnimation / SCNAction技術。 在其他方法中,動畫會隨着時間的推移而不同步。

錳,

我只是在這里猜測或者可以為你激發一個想法:-)

我正在關注你問題的這一部分:“我正在尋找的是一種邏輯,我可以在所有節點上附加動畫,並在以后讓用戶點擊正確的節點時將這些動畫調用在一起。”

我想知道SCNTransaction:[ https://developer.apple.com/documentation/scenekit/scntransaction] [1 ]是否可以做到這一點

或者也許是dispatch.sync或async(完全猜測......但可以提供幫助)[ https://developer.apple.com/documentation/dispatch] [1 ]

或者我離開了標記:-)只是想幫忙....

我們通過分享我們所知道的東西來學習

RAD

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM