如何在SceneKit中反转动画?参数使用疑问及文档咨询
Hey there! Let's tackle your SceneKit animation questions step by step.
First: Clarifying fillsBackward and fillsForward
It sounds like you might have misunderstood what these properties do—they don't control animation direction at all. Here's a breakdown:
fillsBackward: When set totrue, the animation's starting values are applied to the node as soon as the animation is added (even beforeplay()is called). This only matters if the node's initial state doesn't match the animation's starting state. For example, if your animation starts with the character rotated 90 degrees, enabling this would make the character jump to that rotation immediately after adding the animation, not when playback starts.fillsForward: When set totrueandisRemovedOnCompletion = false, the node keeps the animation's final values after the animation finishes. If you're not seeing this work, double-check:- That your animation actually modifies a property (e.g., rotation) that's different from the node's default state.
- That no other animations or direct property changes are overriding the final state after playback ends.
In your code, you're setting these properties correctly on the animation itself, but they won't help with reversing the animation's playback direction.
How to Reverse a SceneKit Animation
Since there's no built-in "reverse" function, here are two reliable ways to achieve this:
1. Use a Negative Speed Value
The simplest method is to set the animation player's speed to a negative number. This directly reverses the playback direction:
// To play the animation in reverse let spinPlayer = character2?.model.animationPlayer(forKey: "spin") spinPlayer?.speed = -1.5 // Negative value = reverse playback spinPlayer?.play()
If the animation has already played partially or fully, adjust the timeOffset to start from the end:
let spinAnimation = spinPlayer?.animation spinPlayer?.timeOffset = spinAnimation?.duration ?? 0 spinPlayer?.speed = -1.5 spinPlayer?.play()
2. Create a Reversed Animation Copy (For Advanced Control)
If you need a permanent reversed animation (not just temporary playback direction), extract the animation's keyframes and reverse their order. For example, for a keyframe-based animation:
// Assuming your animation is a CAKeyframeAnimation if let keyframeAnim = spinAnimation as? CAKeyframeAnimation { // Reverse values and key times to create a backward animation keyframeAnim.values = keyframeAnim.values?.reversed() keyframeAnim.keyTimes = keyframeAnim.keyTimes?.reversed() // Add the reversed animation to your node let reversedPlayer = SCNAnimationPlayer(animation: keyframeAnim) reversedPlayer.isRemovedOnCompletion = false model!.addAnimationPlayer(reversedPlayer, forKey: "spinReverse") }
This is useful if you want to trigger the reversed animation independently of the original.
On SceneKit Documentation
It's true that official SceneKit docs can feel sparse at times. Here are better resources to dive deeper:
- WWDC Session Videos: The WWDC 2017 Session 604 you referenced is a great start—rewatch sections on animation timing and control for practical, context-rich examples.
- Apple Sample Code: The SceneKit 2017 sample code walks through character animation integration, which can clarify how properties like
autoreversesfit into real workflows. - Core Animation Documentation: Since SceneKit animations are built on Core Animation, checking CAAnimation's property docs can give you more context on timing and fill behaviors.
- Community Resources: The Stack Overflow SceneKit community has tons of solved questions on animation reversal—search for specific use cases to see how others have tackled similar problems.
Quick Note on autoreverses
Just to confirm: autoreverses = true makes the animation play forward, then immediately backward in a single playback cycle. It's designed for back-and-forth looping animations, not for playing an animation in reverse from the start, which explains why it didn't fit your need.
Hope this clears things up!
内容的提问来源于stack exchange,提问作者Serus

