Ios SceneKit中的连续变形动画

Ios SceneKit中的连续变形动画,ios,animation,swift2,scenekit,cabasicanimation,Ios,Animation,Swift2,Scenekit,Cabasicanimation,我很难在SceneKit中通过不同的变形目标设置动画。 我有一个变形目标数组,我想通过一个循环来显示它们,每个变形目标之间都有一个动画 从一个几何体到另一个几何体,这很容易。 在中,有一个示例可用于一个变形几何体(morpher.weights[0]): 我想做的是,为变形设置动画。我尝试为每个目标设置几个动画。但在完成第一个动画后,第一个目标的权重再次设置为0 override func viewDidLoad() { super.viewDidLoad() // creat

我很难在SceneKit中通过不同的变形目标设置动画。 我有一个变形目标数组,我想通过一个循环来显示它们,每个变形目标之间都有一个动画

从一个几何体到另一个几何体,这很容易。 在中,有一个示例可用于一个变形几何体(morpher.weights[0]):

我想做的是,为变形设置动画。我尝试为每个目标设置几个动画。但在完成第一个动画后,第一个目标的权重再次设置为0

override func viewDidLoad() {
    super.viewDidLoad()

    // create a new scene
    let scene = SCNScene()

    let vbasic_geom: [Vertex] = [
        [ [0, 0, 0],      [+1.0, +0.0, +0.0] ],
        [ [0, 2, 0],      [+1.0, +0.0, +0.0] ],
        [ [2, 2, 0],      [+1.0, +0.0, +0.0] ]
    ]

    let vmorph1: [Vertex] = [
        [ [0, 0, 0],      [+1.0, +0.0, +0.0] ],
        [ [0, 4, 0],      [+1.0, +0.0, +0.0] ],
        [ [2, 2, 0],      [+1.0, +0.0, +0.0] ]
    ]

    let vmorph2: [Vertex] = [
        [ [0, 0, 0],      [+1.0, +0.0, +0.0] ],
        [ [0, 2, 0],      [+1.0, +0.0, +0.0] ],
        [ [4, 2, 0],      [+1.0, +0.0, +0.0] ]
    ]


    let basic_geom = gen_geometry(vbasic_geom)

    let morph1 = gen_geometry(vmorph1)

    let morph2 = gen_geometry(vmorph2)


    let morpher = SCNMorpher()
    morpher.targets = [morph1, morph2]

    let object = SCNNode(geometry: basic_geom)
    object.morpher = morpher

    //needed for model-layer refresh; implicit animation
    morpher.setWeight(1.0, forTargetAtIndex: 0)
    morpher.setWeight(1.0, forTargetAtIndex: 1)

    //set up animations
    let animation = CABasicAnimation(keyPath: "morpher.weights[0]")
    animation.fromValue = 0.0
    animation.toValue = 1.0
    animation.duration = 5
    animation.beginTime = 0.0
    animation.removedOnCompletion = false

    let animation2 = CABasicAnimation(keyPath: "morpher.weights[1]")
    animation2.fromValue = 0.0;
    animation2.toValue = 1.0
    animation2.duration = 5
    animation2.beginTime = 5.0
    animation.removedOnCompletion = false

    let animationgroup = CAAnimationGroup()
    animationgroup.duration = 10.0
    animationgroup.autoreverses = false
    animationgroup.repeatCount = 10000;

    animationgroup.animations = [animation, animation2]

    object.addAnimation(animationgroup, forKey: "morpher.weights")

    scene.rootNode.addChildNode(object)
GIF

尝试了几种解决方案,但我从未成功:

  • 也许可以将`关键路径:“morpher.weights[0]”更改为` morpher.weights',并将from和toValues设置为类似数组的值。包括更改valueFunction

  • 由于动画发生在表示层上,因此必须将已设置动画的特性保留为完成值。它尝试了“removedOnCompletion”,但似乎不起作用

有人有线索或解决办法吗


如果有必要的话,我可以发布一个链接到整个代码——这里不需要它。

这是CAAnimation的一个常见问题——不仅仅是SceneKit:默认情况下,完成时会删除显式动画,并且呈现值会重置为模型值(显式动画永远不会修改该值)。 有两种解决方案:

  • 改为使用隐式动画(带有 将触发下一个动画的完成块)
  • 将removedOnCompletion设置为NO,并将fillMode设置为FillForward
  • (可选)对于#2:您可以将代理设置为动画,并在将modelValue与presentationValue同步后删除animationDidStop中的动画

    override func viewDidLoad() {
        super.viewDidLoad()
    
        // create a new scene
        let scene = SCNScene()
    
        let vbasic_geom: [Vertex] = [
            [ [0, 0, 0],      [+1.0, +0.0, +0.0] ],
            [ [0, 2, 0],      [+1.0, +0.0, +0.0] ],
            [ [2, 2, 0],      [+1.0, +0.0, +0.0] ]
        ]
    
        let vmorph1: [Vertex] = [
            [ [0, 0, 0],      [+1.0, +0.0, +0.0] ],
            [ [0, 4, 0],      [+1.0, +0.0, +0.0] ],
            [ [2, 2, 0],      [+1.0, +0.0, +0.0] ]
        ]
    
        let vmorph2: [Vertex] = [
            [ [0, 0, 0],      [+1.0, +0.0, +0.0] ],
            [ [0, 2, 0],      [+1.0, +0.0, +0.0] ],
            [ [4, 2, 0],      [+1.0, +0.0, +0.0] ]
        ]
    
    
        let basic_geom = gen_geometry(vbasic_geom)
    
        let morph1 = gen_geometry(vmorph1)
    
        let morph2 = gen_geometry(vmorph2)
    
    
        let morpher = SCNMorpher()
        morpher.targets = [morph1, morph2]
    
        let object = SCNNode(geometry: basic_geom)
        object.morpher = morpher
    
        //needed for model-layer refresh; implicit animation
        morpher.setWeight(1.0, forTargetAtIndex: 0)
        morpher.setWeight(1.0, forTargetAtIndex: 1)
    
        //set up animations
        let animation = CABasicAnimation(keyPath: "morpher.weights[0]")
        animation.fromValue = 0.0
        animation.toValue = 1.0
        animation.duration = 5
        animation.beginTime = 0.0
        animation.removedOnCompletion = false
    
        let animation2 = CABasicAnimation(keyPath: "morpher.weights[1]")
        animation2.fromValue = 0.0;
        animation2.toValue = 1.0
        animation2.duration = 5
        animation2.beginTime = 5.0
        animation.removedOnCompletion = false
    
        let animationgroup = CAAnimationGroup()
        animationgroup.duration = 10.0
        animationgroup.autoreverses = false
        animationgroup.repeatCount = 10000;
    
        animationgroup.animations = [animation, animation2]
    
        object.addAnimation(animationgroup, forKey: "morpher.weights")
    
        scene.rootNode.addChildNode(object)