You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用CAKeyframeAnimation实现SceneKit节点旋转与飞机飞行动画

SceneKit 飞机路径飞行动画实现方案

方案1:优化SCNAction实现带平滑过渡的方形路径

你需要的动作叠加效果可以通过SCNAction.sequence嵌套SCNAction.group实现,将转弯动作和前后段的移动动作做时间重叠,同时添加缓动效果提升真实感:

func animateAirplaneSmoothSquare(nodeToAnimate: SCNNode) {
    let overlapTurnDuration: TimeInterval = 0.8 // 转弯和移动的重叠时间
    let straightMoveDuration: TimeInterval = 2 // 纯直飞的时长
    
    // 第一段X轴移动:总时长包含直飞+重叠转弯阶段
    let moveXFull = SCNAction.moveBy(x: 1, y: 0, z: 0, duration: straightMoveDuration + overlapTurnDuration)
    moveXFull.timingMode = .easeOut // 快进入转弯时减速更符合真实飞行逻辑
    let waitForStraight = SCNAction.wait(duration: straightMoveDuration)
    
    // 转弯阶段同步执行:旋转+启动Z轴移动
    let rotateRight = SCNAction.rotateBy(x: 0, y: -CGFloat(deg2rad(90)), z: 0, duration: overlapTurnDuration * 2)
    rotateRight.timingMode = .easeInEaseOut
    let moveZFull = SCNAction.moveBy(x: 0, y: 0, z: 1, duration: straightMoveDuration + overlapTurnDuration)
    moveZFull.timingMode = .easeIn
    
    // 组合动作序列
    let turnPhase = SCNAction.group([rotateRight, moveZFull])
    let fullSequence = SCNAction.sequence([
        SCNAction.group([moveXFull, waitForStraight]),
        turnPhase
    ])
    
    // 循环4次即可实现完整方形路径飞行
    nodeToAnimate.runAction(SCNAction.repeatForever(fullSequence))
}

方案2:CAKeyframeAnimation实现环形/任意路径飞行

这是更推荐的方案,无需手动拼接旋转和位移动画,系统可以自动处理沿路径的朝向:

原有代码问题修正

你之前的实现存在两个核心问题:

  • rotation关键帧的取值应为SCNVector4(x/y/z为旋转轴,w为旋转弧度),而非SCNVector3
  • 旋转动画和位移动画的时间轴未对齐,导致动作节奏不匹配

环形路径实现代码

func animateAirplaneCirclePath(nodeToAnimate: SCNNode) {
    let circleRadius: CGFloat = 2 // 环形路径半径,单位和3D场景单位保持一致
    // 生成环形路径,可替换为矩形、自定义曲线路径
    let flightPath = UIBezierPath(ovalIn: CGRect(x: -circleRadius, y: -circleRadius, width: circleRadius*2, height: circleRadius*2))
    
    let positionAnim = CAKeyframeAnimation(keyPath: "position")
    positionAnim.path = flightPath.cgPath
    positionAnim.duration = 8 // 飞一圈的总时长
    positionAnim.repeatCount = .infinity
    positionAnim.calculationMode = .paced // 保持匀速飞行
    // 自动沿路径切线调整朝向,无需单独写旋转动画
    positionAnim.rotationMode = .rotateAuto
    // 根据你的飞机模型默认朝向调整偏移量即可
    positionAnim.rotationOffset = .pi / 2
    
    nodeToAnimate.addAnimation(positionAnim, forKey: "circleFlight")
}

如果要实现方形路径,将UIBezierPath的生成逻辑替换为矩形绘制即可,还可以添加圆角实现平滑转弯效果。如果需要模拟真实飞机转弯时的侧倾效果,可以额外添加一个Z轴旋转的关键帧动画,和位移动画的时间轴对齐即可。

内容的提问来源于stack exchange,提问作者Damiano Miazzi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 12:15:06