【发布时间】:2015-06-23 21:39:47
【问题描述】:
我正在使用 SceneKit 加载 Collada (.dae) 文件。
无论我尝试过什么,动画都会连续循环重复,而我只希望它播放一次然后停止。
这里是加载代码,其中 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
}
}
我也尝试过另一种方式:
let 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 文件图标有一个播放按钮,单击此按钮还会连续循环播放图标内的动画。
更新:
我现在注意到,在上面的代码中,我设置了常量“动画”属性,而这并没有复制回实际的场景节点。此外,.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 帧是最后一帧的副本。这行得通,并不引人注目,但似乎不是一个非常优雅的解决方案。
【问题讨论】:
标签: animation scenekit collada