更新该模型时,定位,更新和/或添加或删除与基础模型对应的SceneKit节点的最明智方法是什么?
我不确定如何最好地提出这个问题,所以最简单的例子可能更容易:
我有一些东西,让我们说一个彩色物体的集合,我可能希望使用说法,石英或三维使用SceneKit在二维上表示为正方形。由于底层数据在两种情况下都是相同的,因此抽象模型并定义如下内容似乎更合适:
struct Foo {
var uid: String
var color: UIColor
var position: [Float] // array of 3 floats for x, y, z
}
然后我有:
var collectionOfFoo: [Foo]
然后我可以通过循环collectionOfFoo
并为每个具有适当颜色和位置等的SCNBox
构建我的SceneKit场景。
问题:用户可能会向Foo
添加新的collectionOfFoo
,或删除现有的Foo
,或更改现有的Foo
之一存储的值,然后必须更新SceneKit场景以反映它。摧毁现场并从头开始重建它似乎很浪费,而且速度太慢了。这可能需要每秒调用数百次。
我当前的方法:我给予与给定Foo
对应的SceneKit节点一个与Foo
' s uid
匹配的名称,然后最终手动搜索使用childNodeWithName
的节点层次结构。然而,这实际上并没有很好地扩展(帧速率差),并且感觉“错误”#34;好像这可能是一个更容易/更惯用的方式。我一直在寻找像ReactiveCocoa
之类的东西,因为它似乎解决了这类问题,但我不确定这是否过于复杂。
如果我使用的是Objective-C,我可能会尝试创建一个Foo
类,其中每个实例只保存一个指向相关SceneKit节点的指针;这不会非常优雅,但至少会有效并能产生预期的效果。我只是在寻找一种更好的方法,一种在Swift中运行的方式。
建议非常受欢迎,非常感谢 - 我仍然在制作我的第一个应用程序,并且仍然认为自己是初学者。
答案 0 :(得分:1)
我对Swift一无所知,所以大部分可能都是错的,但这是一个疯狂的猜测:
为什么不切换到Class
而不是Struct
?您的代码不会发生太大变化,但它可以帮助您存储SCNNode,以及任何其他图形表示以及您拥有的数据。
如果无法做到这一点,那么使用单独的字典怎么样?只需使用您已有的uid存储您的SCNNode:
var nodes = [String: SCNNode]()
...
nodes[current.uid] = aNewNode
您还可以随时在场景中添加和删除节点,无需"销毁和重建"。如果我们保留上一个示例,您可以执行以下操作:
nodes[uidToDelete].removeFromParentNode()
另一方面,差的帧速率可能与添加/删除节点的方式无关。尝试enable statistics on your scene,看看你在哪里浪费时间。
答案 1 :(得分:1)
我建议你看一下斯坦福大学的这门课程并看一下MVC讲座:https://itunes.apple.com/gb/course/developing-ios-8-apps-swift/id961180099
他们建议您使用NSNotification
来提醒您的控制器(在您的情况下可能是您的SCNScene
)模型中的更改。然后,您的控制器会进入并更改其视图(或您的情况下为SCNNode
)。这是一个例子:
1。您的模型中发生了一些事情 - 创建了新的Foo
!因此,发布NSNotification
:
let notificationCenter = NSNotificationCenter.defaultCenter()
notificationCenter.postNotificationName("FooWasCreatedNotification",
object: nil,
userInfo: ["Foo": fooInstance])
(为了能够在此处传递Foo
的实例,Foo
需要成为一个类,因为struct
无法添加到userInfo
)
2。在SCNScene
(或您正在使用的任何其他内容)中,收到NSNotification
并更新:
func didRevieveNewFooNotification(notification: NSNotification!) {
if let info = notification.userInfo as? Dictionary<String,AnyObject>,
let foo = info["Foo"] as? Foo {
// Create new node using foo's properties...
// And add it to the array:
collectionOfFoo.append(foo)
}
}
使用NSNotification
可使您的模型非常便携,因为NSNotification
是盲目沟通。因此,您的控制器和节点可以是您想要的任何内容,而无需更改模型。
希望有所帮助。