SceneKit SCNAnimation 如何检测指定动画是否正在播放?
解决方案
你可以通过组合判断SCNAnimationPlayer的多个属性,实现指定动画是否正在播放的检测,核心逻辑如下:
- 首先确认目标节点是否存在对应key的
SCNAnimationPlayer实例 - 其次判断该实例的
paused属性为false(未被主动暂停) - 最后针对非循环动画补充判断播放进度未结束,避免误判已播完自动移除的动画
你可以给SCNNode加一个扩展方法复用判断逻辑:
extension SCNNode { /// 判断指定key对应的动画是否正在播放 func isAnimationPlaying(forKey key: String) -> Bool { // 不存在对应key的播放器,说明动画未加载/已移除 guard let player = self.animationPlayer(forKey: key) else { return false } // 播放器已暂停,不属于播放状态 guard !player.paused else { return false } let animation = player.animation // 非循环且播完自动移除的动画,需要判断是否未播完 if animation.repeatCount == 0 && animation.removedOnCompletion { return player.time < animation.duration } // 循环动画只要未暂停就属于正在播放状态 return true } }
使用时直接调用扩展方法即可,你的原有逻辑可以修改为:
// 要触发的动画对应的固定key,比如Idle动画统一用"anim_idle" let targetAnimationKey = "newanimkey" guard !node.isAnimationPlaying(forKey: targetAnimationKey) else { return } // 后续执行添加动画的逻辑
注意事项
- 每个类型的动画需要绑定固定唯一的key,比如Idle动画固定使用
"anim_idle"、跑步动画固定使用"anim_run",不要每次加载动画都生成随机key,才能正确识别同类型动画是否正在播放 - 如果你的所有动画都是循环播放的,可以直接简化判断逻辑,仅校验播放器存在且
paused为false即可 - 上述逻辑已经兼容
animation.removedOnCompletion = true的场景,不会把已经播放完成自动移除的动画误判为正在播放
内容的提问来源于stack exchange,提问作者ZAY
相关产品推荐
相关产品推荐

