改变子节点的颜色
Change color of child node
目前,当我更改子节点的颜色时,它会导致所有其他子节点的颜色发生变化,这是我不想要的。
我这样改变子节点的颜色:
let materials = node.geometry?.materials as! [SCNMaterial]
let material = materials[0]
material.diffuse.contents = UIColor.grayColor()
默认情况下,如果您有多个节点分配了相同的 SCNGeometry
实例,那么这些节点也有相同的 material。更改 material 会更改使用该 material.
的所有节点的外观
SCNGeometry
对象并不直接表示几何数据 — 它实际上只是一组几何数据和一组 material 之间关联的轻量级表示。因此,当您想在具有不同 material 的多个节点上渲染相同的几何体时,只需复制几何体对象……它们仍将共享基础数据,因此渲染时间成本可以忽略不计,但您您将能够独立更改他们的 material。
复制几何后,您可以独立更改两个几何上的 组 material,但这些组仍然共享相同的 SCNMaterial
实例。 (这很有用,因为一个几何体可以有多个 material,每个 material 都是几个属性的集合,所以尽可能共享它们是有效的。)所以你可以分配新的 materials 到每个几何图形,或取消共享 materials.
// Using copy as a way to get two nodes with the same material
// (but your scene might already have two such nodes)
let node2 = node1.copy() as! SCNNode
// Right now, node2 is sharing geometry. This changes the color of both:
node1.geometry?.firstMaterial?.diffuse.contents = UIColor.redColor()
// Un-share the geometry by copying
node2.geometry = node1.geometry!.copy()
// Un-share the material, too
node2.geometry?.firstMaterial = node1.geometry!.firstMaterial!.copy() as? SCNMaterial
// Now, we can change node2's material without changing node1's:
node2.geometry?.firstMaterial?.diffuse.contents = UIColor.blueColor()
在 Building a Game with SceneKit 的 WWDC 2014 演讲中对此进行了很好的讨论。相关位在视频中的 37:15 或 PDF 中的幻灯片 159 处。
基于 @sambro comment and @rickster 代码,这里是现成的答案:
// Un-share the geometry by copying
node.geometry = node.geometry!.copy() as? SCNGeometry
// Un-share the material, too
node.geometry?.firstMaterial = node.geometry?.firstMaterial!.copy() as? SCNMaterial
// Now, we can change node's material without changing parent and other childs:
node.geometry?.firstMaterial?.diffuse.contents = UIColor.blueColor()
现在已经简化了
let searchNode = node.childNode(withName: "YOUR_CHILD_NODE_NAME", recursively: true)
searchNode?.geometry?.firstMaterial?.diffuse.contents = UIColor.red
在这里,它搜索完整的树。子节点、子子节点等,直到找到具有特定名称的节点。
目前,当我更改子节点的颜色时,它会导致所有其他子节点的颜色发生变化,这是我不想要的。
我这样改变子节点的颜色:
let materials = node.geometry?.materials as! [SCNMaterial]
let material = materials[0]
material.diffuse.contents = UIColor.grayColor()
默认情况下,如果您有多个节点分配了相同的 SCNGeometry
实例,那么这些节点也有相同的 material。更改 material 会更改使用该 material.
SCNGeometry
对象并不直接表示几何数据 — 它实际上只是一组几何数据和一组 material 之间关联的轻量级表示。因此,当您想在具有不同 material 的多个节点上渲染相同的几何体时,只需复制几何体对象……它们仍将共享基础数据,因此渲染时间成本可以忽略不计,但您您将能够独立更改他们的 material。
复制几何后,您可以独立更改两个几何上的 组 material,但这些组仍然共享相同的 SCNMaterial
实例。 (这很有用,因为一个几何体可以有多个 material,每个 material 都是几个属性的集合,所以尽可能共享它们是有效的。)所以你可以分配新的 materials 到每个几何图形,或取消共享 materials.
// Using copy as a way to get two nodes with the same material
// (but your scene might already have two such nodes)
let node2 = node1.copy() as! SCNNode
// Right now, node2 is sharing geometry. This changes the color of both:
node1.geometry?.firstMaterial?.diffuse.contents = UIColor.redColor()
// Un-share the geometry by copying
node2.geometry = node1.geometry!.copy()
// Un-share the material, too
node2.geometry?.firstMaterial = node1.geometry!.firstMaterial!.copy() as? SCNMaterial
// Now, we can change node2's material without changing node1's:
node2.geometry?.firstMaterial?.diffuse.contents = UIColor.blueColor()
在 Building a Game with SceneKit 的 WWDC 2014 演讲中对此进行了很好的讨论。相关位在视频中的 37:15 或 PDF 中的幻灯片 159 处。
基于 @sambro comment and @rickster 代码,这里是现成的答案:
// Un-share the geometry by copying
node.geometry = node.geometry!.copy() as? SCNGeometry
// Un-share the material, too
node.geometry?.firstMaterial = node.geometry?.firstMaterial!.copy() as? SCNMaterial
// Now, we can change node's material without changing parent and other childs:
node.geometry?.firstMaterial?.diffuse.contents = UIColor.blueColor()
现在已经简化了
let searchNode = node.childNode(withName: "YOUR_CHILD_NODE_NAME", recursively: true)
searchNode?.geometry?.firstMaterial?.diffuse.contents = UIColor.red
在这里,它搜索完整的树。子节点、子子节点等,直到找到具有特定名称的节点。