使用 CAKeyframeAnimation 在 Scenekit 中动画旋转节点
Animate rotation node in Scenekit using CAKeyframeAnimation
为了研究 ARKit 和 SceneKit,我正在编写一个简单的应用程序,它应该做两件事:
在 3d 世界中放置一架飞机
为这架飞机制作动画,让这架飞机以圆周方式飞行(如果我能让这架飞机以方形路径飞行,我会很高兴)。
现在,我卡在第二点上了,为飞机设置动画。
我尝试了不同的方法但没有成功。
首先尝试:使用“sequanceAction”制作动画,但正如您从以下代码中看到的那样,平面首先移动到旋转 (Yaxes) 的 X,然后移动到 Z(动画非常丑陋)。
func animataAirplane(nodeToAnimate: SCNNode){
let moveinx = SCNAction.move(to: SCNVector3(nodeToAnimate.position.x + 1,nodeToAnimate.position.y,nodeToAnimate.position.z), duration: 2)
let rotateRight = SCNAction.rotate(by: deg2rad(-90), around: SCNVector3(0, 1, 0), duration: 1)
let moveinz = SCNAction.move(to: SCNVector3(nodeToAnimate.position.x + 1,nodeToAnimate.position.y,nodeToAnimate.position.z + 1), duration: 2)
let sequanceAction = SCNAction.sequence([moveinx, rotateRight, moveinz])
nodeToAnimate.runAction(sequenceAction)
}
我想要的是过度的动画,几乎在 moveX 动作结束时开始旋转动作和 moveinZ,以给出真实平面转动的错觉。
这可能吗?我正在寻找有人指出正确的方向,我应该看什么。
我的第二种方法是尝试“CAKeyframeAnimation”:
但是我找不到确切的方法来组合这个动画:
func animatePlaneKey(nodeToAnimate: SCNNode){
let pos = nodeToAnimate.position
let animation = CAKeyframeAnimation(keyPath: "position")
let pos1 = SCNVector3(pos.x, pos.y, pos.z)
let pos2 = SCNVector3(pos.x + 1 , pos.y, pos.z)
let pos3 = SCNVector3(pos.x + 1 , pos.y, pos.z + 1)
animation.values = [pos1,pos2, pos3]
animation.keyTimes = [0,0.5,1]
animation.calculationMode = .linear
animation.duration = 10
animation.repeatCount = 1
animation.isAdditive = true
let animation2 = CAKeyframeAnimation(keyPath: "rotation")
let pos1rot = SCNVector3(nodeToAnimate.eulerAngles.x, nodeToAnimate.eulerAngles.y, nodeToAnimate.eulerAngles.z)
let pos2rot = SCNVector3(nodeToAnimate.eulerAngles.x + Float(deg2rad(90)), nodeToAnimate.eulerAngles.y + Float(deg2rad(90)), nodeToAnimate.eulerAngles.z + Float(deg2rad(90)))
animation2.values = [pos1rot,pos2rot]
animation2.keyTimes = [0,1]
animation2.duration = 2
animation2.repeatCount = 1
animation2.isAdditive = true
nodeToAnimate.addAnimation(animation, forKey: "position")
nodeToAnimate.addAnimation(animation2, forKey: "rotation")
}
如果有人能指出正确的方向来模拟这个飞行动画,我会很高兴。
非常感谢。
这是您的代码的工作版本:
func animatePlaneKey(nodeToAnimate: SCNNode) {
let pos = nodeToAnimate.position
let animation = CAKeyframeAnimation(keyPath: "position")
let pos1 = SCNVector3(pos.x, pos.y, pos.z)
let pos2 = SCNVector3(pos.x + 1 , pos.y, pos.z)
let pos3 = SCNVector3(pos.x + 1 , pos.y, pos.z + 1)
animation.values = [pos1,pos2, pos3]
animation.keyTimes = [0,0.5,1]
animation.calculationMode = .linear
animation.duration = 10
animation.repeatCount = 1
animation.isAdditive = true
let animation2 = CAKeyframeAnimation(keyPath: "rotation")
let pos1rot = SCNVector4(0, 0, 0, 0)
let pos2rot = SCNVector4(0, 1, 0, CGFloat(Float.pi/2))
animation2.values = [pos1rot, pos2rot]
animation2.keyTimes = [0, 1]
animation2.duration = 20
animation2.repeatCount = 1
animation2.isAdditive = true
nodeToAnimate.addAnimation(animation, forKey: "position")
nodeToAnimate.addAnimation(animation2, forKey: "spin around")
}
为了研究 ARKit 和 SceneKit,我正在编写一个简单的应用程序,它应该做两件事:
在 3d 世界中放置一架飞机
为这架飞机制作动画,让这架飞机以圆周方式飞行(如果我能让这架飞机以方形路径飞行,我会很高兴)。
现在,我卡在第二点上了,为飞机设置动画。
我尝试了不同的方法但没有成功。
首先尝试:使用“sequanceAction”制作动画,但正如您从以下代码中看到的那样,平面首先移动到旋转 (Yaxes) 的 X,然后移动到 Z(动画非常丑陋)。
func animataAirplane(nodeToAnimate: SCNNode){
let moveinx = SCNAction.move(to: SCNVector3(nodeToAnimate.position.x + 1,nodeToAnimate.position.y,nodeToAnimate.position.z), duration: 2)
let rotateRight = SCNAction.rotate(by: deg2rad(-90), around: SCNVector3(0, 1, 0), duration: 1)
let moveinz = SCNAction.move(to: SCNVector3(nodeToAnimate.position.x + 1,nodeToAnimate.position.y,nodeToAnimate.position.z + 1), duration: 2)
let sequanceAction = SCNAction.sequence([moveinx, rotateRight, moveinz])
nodeToAnimate.runAction(sequenceAction)
}
我想要的是过度的动画,几乎在 moveX 动作结束时开始旋转动作和 moveinZ,以给出真实平面转动的错觉。
这可能吗?我正在寻找有人指出正确的方向,我应该看什么。
我的第二种方法是尝试“CAKeyframeAnimation”:
但是我找不到确切的方法来组合这个动画:
func animatePlaneKey(nodeToAnimate: SCNNode){
let pos = nodeToAnimate.position
let animation = CAKeyframeAnimation(keyPath: "position")
let pos1 = SCNVector3(pos.x, pos.y, pos.z)
let pos2 = SCNVector3(pos.x + 1 , pos.y, pos.z)
let pos3 = SCNVector3(pos.x + 1 , pos.y, pos.z + 1)
animation.values = [pos1,pos2, pos3]
animation.keyTimes = [0,0.5,1]
animation.calculationMode = .linear
animation.duration = 10
animation.repeatCount = 1
animation.isAdditive = true
let animation2 = CAKeyframeAnimation(keyPath: "rotation")
let pos1rot = SCNVector3(nodeToAnimate.eulerAngles.x, nodeToAnimate.eulerAngles.y, nodeToAnimate.eulerAngles.z)
let pos2rot = SCNVector3(nodeToAnimate.eulerAngles.x + Float(deg2rad(90)), nodeToAnimate.eulerAngles.y + Float(deg2rad(90)), nodeToAnimate.eulerAngles.z + Float(deg2rad(90)))
animation2.values = [pos1rot,pos2rot]
animation2.keyTimes = [0,1]
animation2.duration = 2
animation2.repeatCount = 1
animation2.isAdditive = true
nodeToAnimate.addAnimation(animation, forKey: "position")
nodeToAnimate.addAnimation(animation2, forKey: "rotation")
}
如果有人能指出正确的方向来模拟这个飞行动画,我会很高兴。
非常感谢。
这是您的代码的工作版本:
func animatePlaneKey(nodeToAnimate: SCNNode) {
let pos = nodeToAnimate.position
let animation = CAKeyframeAnimation(keyPath: "position")
let pos1 = SCNVector3(pos.x, pos.y, pos.z)
let pos2 = SCNVector3(pos.x + 1 , pos.y, pos.z)
let pos3 = SCNVector3(pos.x + 1 , pos.y, pos.z + 1)
animation.values = [pos1,pos2, pos3]
animation.keyTimes = [0,0.5,1]
animation.calculationMode = .linear
animation.duration = 10
animation.repeatCount = 1
animation.isAdditive = true
let animation2 = CAKeyframeAnimation(keyPath: "rotation")
let pos1rot = SCNVector4(0, 0, 0, 0)
let pos2rot = SCNVector4(0, 1, 0, CGFloat(Float.pi/2))
animation2.values = [pos1rot, pos2rot]
animation2.keyTimes = [0, 1]
animation2.duration = 20
animation2.repeatCount = 1
animation2.isAdditive = true
nodeToAnimate.addAnimation(animation, forKey: "position")
nodeToAnimate.addAnimation(animation2, forKey: "spin around")
}