如何将结构或 class 对象附加到 SCNNode
How to attach a struct or class object to a SCNNode
我正在尝试创建一个场景,让不同的用户可以展示不同的汽车。当用户首次登录到应用程序时,他们会获得 uid、用户名等。当他们选择汽车时,汽车模型具有汽车类型和标识他们的用户对象。
我可以创建一辆汽车并实施 hitTest 来查找哪辆汽车被点击了。我想不通的是如何为被窃听的汽车分配数据模型,以便我知道谁是谁?
到目前为止,我在节点上发现的唯一 属性 是 node.name
,我可以将 userId 附加到它,然后通过一组用户来找出谁是谁,但事实并非如此;如果我有很多用户,这似乎很实用。删除节点时我还需要 属性:
sceneView.session.pause()
sceneView.scene.rootNode.enumerateChildNodes { (node, _) in
// this would actually remove all the ferraries on the scene but this is just an example
if node.name == "ferrari" {
node.removeFromParentNode()
}
}
如何将数据模型附加到 SCNNode?
class User {
var userId: String?
var username: String?
}
class RaceCar {
var user: User?
var type: String?
}
// user creates an account and picks a ferrari
let raceCar = RaceCar()
let type = raceCar.type!
switch type {
case "ferrari":
createFerrariAndAddItToScene(raceCar)
case "bmw":
...etc
}
func createFerrariAndAddItToScene(_ raceCar: RaceCar) {
let image = art.scnassests/"\(raceCar.typ!e).jpg"
let material = SCNMaterial()
material.diffuse.contents = image
let plane = SCNPlane(width: 0.1, height: 0.1)
plane.materials = [material]
let node = SCNNode()
node.name = raceCar.type!
node.geometry = plane
node.position = SCNVector(0.0, 0.0, -0.2)
sceneView.scene.rootNode.addChildNode(node)
}
@objc func nodeWasTapped(_ sender: UITapGestureRecognizer) {
guard let sceneView = sender.view as? ARSCNView else { return }
let touchLocation = sender.location(in: sceneView)
let hitResults = sceneView.hitTest(touchLocation, options: [:])
if !hitResults.isEmpty {
guard let hitResult = hitResults.first else { return }
let node = hitResult.node
print(node.name) // I need to get some info from the dataModel here like node.raceCar.user.username or node.raceCar.user.userId
}
}
您可以子class SCNNode
并向其中添加您需要的任何数据模型:
class CarNode: SCNNode {
var raceCar: RaceCar?
init(raceCar: RaceCar, geometry: SCNGeometry) {
super.init()
self.geometry = geometry
self.raceCar = raceCar
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
要创建新节点,只需使用这个新的 class:
func createFerrariAndAddItToScene(_ raceCar: RaceCar) {
...
let node = CarNode(raceCar: raceCar, geometry: plane)
...
}
要访问您的数据模型,您可以这样做:
@objc func nodeWasTapped(_ sender: UITapGestureRecognizer) {
...
if let node = hitResult.node as? CarNode {
print(node.raceCar.user.username)
}
}
我运气不错 setValue:ForKey:
node.setValue(tile, forKey: "tile")
...
if let tile = node.value(forKey: "tile") as? Tile {
...
}
我正在尝试创建一个场景,让不同的用户可以展示不同的汽车。当用户首次登录到应用程序时,他们会获得 uid、用户名等。当他们选择汽车时,汽车模型具有汽车类型和标识他们的用户对象。
我可以创建一辆汽车并实施 hitTest 来查找哪辆汽车被点击了。我想不通的是如何为被窃听的汽车分配数据模型,以便我知道谁是谁?
到目前为止,我在节点上发现的唯一 属性 是 node.name
,我可以将 userId 附加到它,然后通过一组用户来找出谁是谁,但事实并非如此;如果我有很多用户,这似乎很实用。删除节点时我还需要 属性:
sceneView.session.pause()
sceneView.scene.rootNode.enumerateChildNodes { (node, _) in
// this would actually remove all the ferraries on the scene but this is just an example
if node.name == "ferrari" {
node.removeFromParentNode()
}
}
如何将数据模型附加到 SCNNode?
class User {
var userId: String?
var username: String?
}
class RaceCar {
var user: User?
var type: String?
}
// user creates an account and picks a ferrari
let raceCar = RaceCar()
let type = raceCar.type!
switch type {
case "ferrari":
createFerrariAndAddItToScene(raceCar)
case "bmw":
...etc
}
func createFerrariAndAddItToScene(_ raceCar: RaceCar) {
let image = art.scnassests/"\(raceCar.typ!e).jpg"
let material = SCNMaterial()
material.diffuse.contents = image
let plane = SCNPlane(width: 0.1, height: 0.1)
plane.materials = [material]
let node = SCNNode()
node.name = raceCar.type!
node.geometry = plane
node.position = SCNVector(0.0, 0.0, -0.2)
sceneView.scene.rootNode.addChildNode(node)
}
@objc func nodeWasTapped(_ sender: UITapGestureRecognizer) {
guard let sceneView = sender.view as? ARSCNView else { return }
let touchLocation = sender.location(in: sceneView)
let hitResults = sceneView.hitTest(touchLocation, options: [:])
if !hitResults.isEmpty {
guard let hitResult = hitResults.first else { return }
let node = hitResult.node
print(node.name) // I need to get some info from the dataModel here like node.raceCar.user.username or node.raceCar.user.userId
}
}
您可以子class SCNNode
并向其中添加您需要的任何数据模型:
class CarNode: SCNNode {
var raceCar: RaceCar?
init(raceCar: RaceCar, geometry: SCNGeometry) {
super.init()
self.geometry = geometry
self.raceCar = raceCar
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
要创建新节点,只需使用这个新的 class:
func createFerrariAndAddItToScene(_ raceCar: RaceCar) {
...
let node = CarNode(raceCar: raceCar, geometry: plane)
...
}
要访问您的数据模型,您可以这样做:
@objc func nodeWasTapped(_ sender: UITapGestureRecognizer) {
...
if let node = hitResult.node as? CarNode {
print(node.raceCar.user.username)
}
}
我运气不错 setValue:ForKey:
node.setValue(tile, forKey: "tile")
...
if let tile = node.value(forKey: "tile") as? Tile {
...
}