SCNAction回调只在设备上调用一次,并在模拟器上正常调用

时间:2016-02-16 23:06:08

标签: ios swift scenekit

修改

我比较了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何时完成执行?

1 个答案:

答案 0 :(得分:1)

我刚刚在OS X游乐场尝试过你的代码,它运行得很好。红色块向右移动并在屏幕外消失。

0 enter
0 callback
1 enter
1 callback
2 enter
2 callback

您对runAction(_:completionHandler:)协议中定义的SCNActionable的使用看起来是正确的。

编辑:我尝试使用运行9.2的iPad和iPhone硬件,在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)
        }
    }
}
}