场景工具包(Swift):取消隐藏或重新添加隐藏/删除的节点

时间:2017-07-12 13:55:13

标签: swift scenekit

我正在尝试创建一个游戏,其中有人点击一个盒子,这使它消失。我的问题是“重新启动”游戏并重新添加所有以前隐藏/删除的框。

我创建了一行像这样的框:

func addBoxes() {

    for _ in 0..<5 {

        let sphereGeometry = SCNBox(width: 1, height: 1, length: 1, chamferRadius: 0)
        let sphereNode: SCNNode! = SCNNode(geometry: sphereGeometry)
        sphereNode.position = SCNVector3(x: x, y: y, z: z)

        scnScene.rootNode.addChildNode(sphereNode)
}

之后我更新了x,y和z的位置。

这一切都很漂亮,我隐藏了一个像这样的小盒子:

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

    let touch = touches.first!
    let location = touch.location(in: scnView)
    let hitResults = scnView.hitTest(location, options: nil)

    if let result = hitResults.first {

        let node = result.node
        node.isHidden = true
    }
}

在点击并隐藏所有方框后,游戏应该暂时重置,所以取消隐藏所有方框:

func newGame() {

    // I've tried this and various versions of it, with no success
    for child in scnScene.rootNode.childNodes {

        child.isHidden = false
    }
}

但是,这给了我:

fatal error: unexpectedly found nil while unwrapping an Optional value

我也试过child.removeFromParentNode(),然后尝试将节点重新添加到场景中,但这会引发同样的错误。

有人能指出我在正确的方向吗?如何取消隐藏在for循环中创建的一个或所有节点?

1 个答案:

答案 0 :(得分:2)

隐藏和取消隐藏的工作正常:

var targetsToDo: Int = 0
let maximumNumberOfTargets = 5

func loadGame() {
    targetsToDo = maximumNumberOfTargets

    scnScene = SCNScene()
    scnView.scene = scnScene

    for i in 1...maximumNumberOfTargets {
        let box = SCNBox(width: 1, height: 1, length: 1, chamferRadius: 0.1)
        let node = SCNNode(geometry: box)
        node.name = "Box \(i)"
        scnScene.rootNode.addChildNode(node)
        node.position = getRandomPosition()
    }
}

@objc func handleTouch(recognizer: UITapGestureRecognizer) {
    let point = recognizer.location(in: view)
    print("Touch at \(NSStringFromCGPoint(point))")
    if let node = scnView.hitTest(point).first?.node {
        print(node.name ?? "")
        node.isHidden = true
        targetsToDo -= 1

        if targetsToDo == 0 {
            resetGame()
        }
    }
}

func resetGame() {
    targetsToDo = maximumNumberOfTargets

    for child in scnScene.rootNode.childNodes {
        child.isHidden = false
        child.position = getRandomPosition()
    }
}

可以找到一个完整的工作场所here