我将使用SceneKit加载Collada (.dae)文件。
无论我尝试了什么,动画都会在循环中不断重复播放。但我只想让它播放一次然后停止。
以下是我的加载代码,其中sceneView是我的SCNView:
场景正确加载,所需的动画在加载时播放,但以连续循环的方式播放。
我已尝试删除所有动画,如下所示:
我也尝试了另一种方法:
让keys等于sceneView.scene!.rootNode.animationKeys(),以获取所有动画关键帧。
实际上只有一个动画附加到一个子节点上。(我也尝试过使用实际的动画ID字符串来替换上面的“key”进行设置。)上面显示了“Initial Repeat count:inf”,并在之后检查时确实设置为1。但是,动画仍然在无限循环中运行 :-(。任何帮助解决此问题的建议都将不胜感激。
进一步更新: 现在,我使用Maya创建了一个简单的动画,并创建了一个新的Collada文件,出于某种原因,上面尝试的其中一种方法实际上起作用了。
无论我尝试了什么,动画都会在循环中不断重复播放。但我只想让它播放一次然后停止。
以下是我的加载代码,其中sceneView是我的SCNView:
//Load the scene and play
let scene = SCNScene(named: "Scenes.scnassets/test4.dae")
sceneView.scene = scene
sceneView.autoenablesDefaultLighting = true
sceneView.allowsCameraControl = true
场景正确加载,所需的动画在加载时播放,但以连续循环的方式播放。
我已尝试删除所有动画,如下所示:
sceneView.scene?.rootNode.removeAllAnimations()
但似乎没有任何效果。
我还尝试检索所有动画并将repeatCount设置为1甚至为0。
let url = NSBundle.mainBundle().URLForResource("Scenes.scnassets/test4", withExtension: "dae")
let sceneSource = SCNSceneSource(URL:url!, options: nil)
let animationIndentifiers = sceneSource?.identifiersOfEntriesWithClass(CAAnimation)
if let ids = animationIndentifiers
{
for id in ids {
let animation: CAAnimation = sceneSource!.entryWithIdentifier(id as! String, withClass: CAAnimation.self)! as! CAAnimation
animation.repeatCount = 1
}
}
我也尝试了另一种方法:
让keys等于sceneView.scene!.rootNode.animationKeys(),以获取所有动画关键帧。
if let theKeys = keys {
for key in theKeys {
let animation = sceneView.scene?.rootNode.animationForKey(key as! String)
animation?.repeatCount = 1
}
}
但是我还是没有成功。
在Collada文件中,我找不到明显导致动画重复的原因。然而,我注意到我的Mac磁盘上的.dae文件图标有一个播放按钮,点击它也会循环播放图标内部的动画。
更新:
现在我注意到在上面的代码中,我正在设置常量“animation”属性,但这并没有被复制回实际的场景节点。此外,.dae文件中唯一的动画是在子节点中。所以这是我的下一个尝试:
//Get the child nodes
let children = scene?.rootNode.childNodes
//Initialise a childNode counter
var childCount = 0
//Iterate through the child nodes
if let theChildren = children {
for child in theChildren {
let keys = child.animationKeys() //get all the animation keys
//Iterate through the animations
if let theKeys = keys {
for key in theKeys {
let animation = child.animationForKey(key as! String)
println("Initial Repeat count: \(animation.repeatCount)")
animation.repeatCount = 1
//Remove existing animation
scene?.rootNode.childNodes[childCount].removeAnimationForKey(key as! String)
//Add amended animation
scene?.rootNode.childNodes[childCount].addAnimation(animation, forKey: key as! String)
}
}
childCount++
}
}
实际上只有一个动画附加到一个子节点上。(我也尝试过使用实际的动画ID字符串来替换上面的“key”进行设置。)上面显示了“Initial Repeat count:inf”,并在之后检查时确实设置为1。但是,动画仍然在无限循环中运行 :-(。任何帮助解决此问题的建议都将不胜感激。
进一步更新: 现在,我使用Maya创建了一个简单的动画,并创建了一个新的Collada文件,出于某种原因,上面尝试的其中一种方法实际上起作用了。
func sceneSetup() {
let scene = SCNScene(named: "Scenes.scnassets/test10.dae")
let children = scene?.rootNode.childNodes
var childCount = 0
if let theChildren = children {
for child in theChildren {
let keys = child.animationKeys() //get all the animation keys
if let theKeys = keys {
for key in theKeys {
let animation = child.animationForKey(key as! String)
animation.repeatCount = 1
scene?.rootNode.childNodes[childCount].removeAnimationForKey(key as! String)
scene?.rootNode.childNodes[childCount].addAnimation(animation, forKey: key as! String)
}
}
childCount++
}
}
sceneView.scene = scene
sceneView.autoenablesDefaultLighting = true
}
如果有人能解释一下那就太好了!
啊,但还有另一个问题!
这是动画的起始帧:
这是我们想要达到的结束帧:
但在动画的结尾处,场景会跳回到起始视图。
我通过修改动画使第1帧成为最终帧的副本来“修复”此问题。 这可以工作,并且不会引起注意,但似乎并不是一个非常优雅的解决方案。