为何使用CAKeyframeAnimation无法为SCNNode的eulerAngle属性实现动画
问题原因及解决方法
导致旋转动画无法运行的核心原因如下:
- keyPath与传入值的类型不匹配:你当前使用的keyPath为
rotation,但SCNNode的rotation属性为SCNVector4类型,前三个分量代表旋转轴,第四个分量代表旋转弧度,而你传入的动画值是SCNVector3类型,类型不匹配导致动画无法被系统识别执行。如果你要操作的是eulerAngles属性,对应的keyPath应该直接填写eulerAngles,该属性本身就是SCNVector3类型,和你构造的rot0、rot1类型完全匹配。 - 补充说明:
isAdditive = true配置本身不会导致动画失效,仅会在节点存在其他变换约束或动画时,影响最终的叠加效果,不是本次问题的核心诱因。
修复方案1:直接操作eulerAngles(推荐,符合你的原始逻辑预期)
func animatePlaneKey(nodeToAnimate: SCNNode){ // 调整keyPath为eulerAngles let animation2 = CAKeyframeAnimation(keyPath: "eulerAngles") let angles = nodeToAnimate.eulerAngles let rot0 = SCNVector3(angles.x, angles.y, angles.z) let rot1 = SCNVector3(angles.x, angles.y + Float(deg2rad(45)) , angles.z) animation2.values = [rot0, rot1] animation2.keyTimes = [0, 1] animation2.duration = 2 animation2.repeatCount = .infinity animation2.isAdditive = true // forKey参数可同步调整为对应属性名,也可保持自定义值 nodeToAnimate.addAnimation(animation2, forKey: "eulerAngles") }
修复方案2:保留rotation keyPath,调整值类型为SCNVector4
如果你确实需要使用rotation属性实现动画,可按照该属性的类型要求构造值,以下示例为绕Y轴旋转45度的实现:
func animatePlaneKey(nodeToAnimate: SCNNode){ let animation2 = CAKeyframeAnimation(keyPath: "rotation") // SCNVector4的前三位为旋转轴,第四位为旋转弧度 let rot0 = SCNVector4(0, 1, 0, 0) let rot1 = SCNVector4(0, 1, 0, Float(deg2rad(45))) animation2.values = [rot0, rot1] animation2.keyTimes = [0, 1] animation2.duration = 2 animation2.repeatCount = .infinity animation2.isAdditive = true nodeToAnimate.addAnimation(animation2, forKey: "rotation") }
内容的提问来源于stack exchange,提问作者Damiano Miazzi
相关产品推荐
相关产品推荐

