SCNAction 回调仅在设备上调用一次并在模拟器上正确调用
SCNAction callback called only once on device and properly on simulator
编辑
我比较了 iPhone(6+、9.3 (13E5200d))和 iOS 模拟器(6+ 9.3 (13E5200d))之间的运行结果,这是我的默认值。模拟器按预期工作。为什么两者之间存在差异?
我有一个看似简单的设置,我想在触摸时执行一系列动画。为此,我雇用了 SCNAction
。在每个动画之后我想重新评估某些事情,所以我没有一个很长的 SCNAction.sequence()
,而是一个 step
函数,我在完成处理程序中调用它。问题是在任意数量的步骤之后没有调用完成处理程序。
在这种情况下,它是一个步骤。
let path = [
SCNAction.sequence([
SCNAction.moveBy(SCNVector3(2.7, 0, 0), duration: 0.25),
SCNAction.waitForDuration(1)
]),
SCNAction.sequence([
SCNAction.moveBy(SCNVector3(2.7, 0, 0), duration: 0.25),
SCNAction.waitForDuration(1)
]),
SCNAction.sequence([
SCNAction.moveBy(SCNVector3(2.7, 0, 0), duration: 0.25),
SCNAction.waitForDuration(1)
]),
]
let nodeGeometry = SCNBox(width: 2.7, height: 2.7, length: 2.7, chamferRadius: 0)
nodeGeometry.firstMaterial = SCNMaterial()
nodeGeometry.firstMaterial?.diffuse.contents = UIColor.redColor()
let node = SCNNode(geometry: nodeGeometry)
scene.rootNode.addChildNode(node)
func step (index: Int) {
print(index, "enter")
node.runAction(path[index]) {
print(index, "callback")
if ((index + 1) < path.count) {
step(index + 1)
}
}
}
step(0)
此代码产生以下序列
0 enter
0 callback
1 enter
我没有收到第二次回电。为什么?我如何知道 SCNAction
何时完成执行?
我刚刚在 OS X 游乐场中尝试了您的代码,它运行良好。红色块向右移动并消失在屏幕外。
0 enter
0 callback
1 enter
1 callback
2 enter
2 callback
您对 runAction(_:completionHandler:)
的使用,定义在 SCNActionable
协议上,看起来是正确的。
编辑:我尝试使用 iPad 和 iPhone 硬件 运行ning 9.2,在 Xcode 7.2.x 和 7.3.beta3 下。下面的代码稍作修改以安抚 Clang 众神,就像您描述的那样工作。要 运行,从一个 Xcode SceneKit 游戏模板开始,用下面的代码替换 GameViewController 定义,并让项目的其余部分保持不变。
class GameViewController: UIViewController {
let path = [
SCNAction.sequence([
SCNAction.moveBy(SCNVector3(2.7, 0, 0), duration: 0.25),
SCNAction.waitForDuration(1)
]),
SCNAction.sequence([
SCNAction.moveBy(SCNVector3(2.7, 0, 0), duration: 0.25),
SCNAction.waitForDuration(1)
]),
SCNAction.sequence([
SCNAction.moveBy(SCNVector3(2.7, 0, 0), duration: 0.25),
SCNAction.waitForDuration(1)
]),
]
var boxNode: SCNNode?
override func viewDidLoad() {
super.viewDidLoad()
let scene = SCNScene()
let sceneView = view as! SCNView
sceneView.scene = scene
sceneView.backgroundColor = UIColor.darkGrayColor()
let nodeGeometry = SCNBox(width: 2.7, height: 2.7, length: 2.7, chamferRadius: 0)
nodeGeometry.firstMaterial = SCNMaterial()
nodeGeometry.firstMaterial?.diffuse.contents = UIColor.redColor()
boxNode = SCNNode(geometry: nodeGeometry)
scene.rootNode.addChildNode(boxNode!)
let sphereNode = SCNNode(geometry: SCNSphere(radius: 1))
sphereNode.position = SCNVector3Make(7, 0, 4)
scene.rootNode.addChildNode(sphereNode)
}
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
step(0)
}
func step (index: Int) {
print(index, "enter")
boxNode!.runAction(path[index]) {
print(index, "callback")
if ((index + 1) < self.path.count) {
self.step(index + 1)
}
}
}
}
编辑
我比较了 iPhone(6+、9.3 (13E5200d))和 iOS 模拟器(6+ 9.3 (13E5200d))之间的运行结果,这是我的默认值。模拟器按预期工作。为什么两者之间存在差异?
我有一个看似简单的设置,我想在触摸时执行一系列动画。为此,我雇用了 SCNAction
。在每个动画之后我想重新评估某些事情,所以我没有一个很长的 SCNAction.sequence()
,而是一个 step
函数,我在完成处理程序中调用它。问题是在任意数量的步骤之后没有调用完成处理程序。
在这种情况下,它是一个步骤。
let path = [
SCNAction.sequence([
SCNAction.moveBy(SCNVector3(2.7, 0, 0), duration: 0.25),
SCNAction.waitForDuration(1)
]),
SCNAction.sequence([
SCNAction.moveBy(SCNVector3(2.7, 0, 0), duration: 0.25),
SCNAction.waitForDuration(1)
]),
SCNAction.sequence([
SCNAction.moveBy(SCNVector3(2.7, 0, 0), duration: 0.25),
SCNAction.waitForDuration(1)
]),
]
let nodeGeometry = SCNBox(width: 2.7, height: 2.7, length: 2.7, chamferRadius: 0)
nodeGeometry.firstMaterial = SCNMaterial()
nodeGeometry.firstMaterial?.diffuse.contents = UIColor.redColor()
let node = SCNNode(geometry: nodeGeometry)
scene.rootNode.addChildNode(node)
func step (index: Int) {
print(index, "enter")
node.runAction(path[index]) {
print(index, "callback")
if ((index + 1) < path.count) {
step(index + 1)
}
}
}
step(0)
此代码产生以下序列
0 enter
0 callback
1 enter
我没有收到第二次回电。为什么?我如何知道 SCNAction
何时完成执行?
我刚刚在 OS X 游乐场中尝试了您的代码,它运行良好。红色块向右移动并消失在屏幕外。
0 enter
0 callback
1 enter
1 callback
2 enter
2 callback
您对 runAction(_:completionHandler:)
的使用,定义在 SCNActionable
协议上,看起来是正确的。
编辑:我尝试使用 iPad 和 iPhone 硬件 运行ning 9.2,在 Xcode 7.2.x 和 7.3.beta3 下。下面的代码稍作修改以安抚 Clang 众神,就像您描述的那样工作。要 运行,从一个 Xcode SceneKit 游戏模板开始,用下面的代码替换 GameViewController 定义,并让项目的其余部分保持不变。
class GameViewController: UIViewController {
let path = [
SCNAction.sequence([
SCNAction.moveBy(SCNVector3(2.7, 0, 0), duration: 0.25),
SCNAction.waitForDuration(1)
]),
SCNAction.sequence([
SCNAction.moveBy(SCNVector3(2.7, 0, 0), duration: 0.25),
SCNAction.waitForDuration(1)
]),
SCNAction.sequence([
SCNAction.moveBy(SCNVector3(2.7, 0, 0), duration: 0.25),
SCNAction.waitForDuration(1)
]),
]
var boxNode: SCNNode?
override func viewDidLoad() {
super.viewDidLoad()
let scene = SCNScene()
let sceneView = view as! SCNView
sceneView.scene = scene
sceneView.backgroundColor = UIColor.darkGrayColor()
let nodeGeometry = SCNBox(width: 2.7, height: 2.7, length: 2.7, chamferRadius: 0)
nodeGeometry.firstMaterial = SCNMaterial()
nodeGeometry.firstMaterial?.diffuse.contents = UIColor.redColor()
boxNode = SCNNode(geometry: nodeGeometry)
scene.rootNode.addChildNode(boxNode!)
let sphereNode = SCNNode(geometry: SCNSphere(radius: 1))
sphereNode.position = SCNVector3Make(7, 0, 4)
scene.rootNode.addChildNode(sphereNode)
}
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
step(0)
}
func step (index: Int) {
print(index, "enter")
boxNode!.runAction(path[index]) {
print(index, "callback")
if ((index + 1) < self.path.count) {
self.step(index + 1)
}
}
}
}