场景工具包(Swift):取消隐藏或重新添加隐藏/删除的节点
Scene kit (Swift): Unhide or re-add hidden / removed nodes
我正在尝试创建一个游戏,在该游戏中,有人点击一个框,它就会消失。我的问题是 'restarting' 游戏和重新添加所有以前隐藏/删除的盒子。
我像这样创建了一排框:
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 循环中创建的一个或所有节点?
隐藏和取消隐藏工作正常,如下所示:
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。
我正在尝试创建一个游戏,在该游戏中,有人点击一个框,它就会消失。我的问题是 'restarting' 游戏和重新添加所有以前隐藏/删除的盒子。
我像这样创建了一排框:
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 循环中创建的一个或所有节点?
隐藏和取消隐藏工作正常,如下所示:
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。