使用SCNTransaction动画SCNNode.scale无效,该如何解决?
问题
尝试使用SCNTransaction为SCNNode的scale属性添加动画,但无动画效果,新的缩放值会立即生效(材质漫反射颜色动画也存在同样问题):
let balloon: SCNNode SCNTransaction.begin() SCNTransaction.animationDuration = 4 SCNTransaction.animationTimingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.linear) balloon.scale.x = 2.28 balloon.scale.y = 2.28 balloon.scale.z = 2.28 // or balloon.scale = SCNVector3(2.28, 2.28, 2.28) SCNTransaction.commit()
而使用SCNAction的代码可以正常生效:
balloon.runAction(SCNAction.scale(to: 2.28, duration: 4), forKey: "scale") DispatchQueue.main.asyncAfter(deadline: .now() + 1) { [self] in balloon.removeAction(forKey: "scale") }
倾向于使用SCNTransaction(可直接设置新值替换/停止动画、具备原子性),请问忽略了什么?
解决方案
你忽略的可能是以下几个常见问题:
- 必须在主线程执行事务:SceneKit的所有节点属性修改和动画事务都必须在主线程操作,若在后台线程调用这段代码,动画会直接跳转到目标值而无过渡效果。
- 节点未加入场景树:如果
balloon节点还未被添加到SCNScene的根节点或其子节点中,SceneKit不会为其属性变更触发动画——只有场景中的节点才会被纳入渲染循环和动画系统。 - 存在冲突的动画/属性锁定:如果节点当前有正在运行的SCNAction、CAAnimation或者其他SCNTransaction动画,新的事务动画可能会被覆盖或忽略。可以先通过
balloon.removeAllActions()清除已有动作,再尝试事务动画。 - 优先设置完整向量值:虽然文档标注单个分量可动画,但直接设置完整的
SCNVector3值更可靠,避免因单个分量修改导致SceneKit未正确识别动画触发条件。
另外,可添加事务完成回调验证事务是否被正确执行:
SCNTransaction.begin() SCNTransaction.animationDuration = 4 SCNTransaction.setAnimationCompletionBlock { print("动画完成") } balloon.scale = SCNVector3(2.28, 2.28, 2.28) SCNTransaction.commit()
如果回调能正常打印,说明事务本身生效,问题可能出在节点的场景状态或线程上。
内容的提问来源于stack exchange,提问作者oxygen
相关产品推荐
相关产品推荐

