停止以编程方式与其克隆共享节点的几何

Lar*_*isa 7 scenekit swift

创建对象的副本时,几何及其属性(材质...)将与该对象共享.
在Xcode场景编辑器中,您可以通过设置Geometry Sharing(下Attributes Inspector)来轻松禁用它Unshare.

我想以编程方式实现相同的功能,但在SceneKit文档中找不到任何类似的属性.
我找到了一个类似的帖子,有人建议复制对象,它的几何和它的材料.我试过这样做但没有成功.

这是我的代码的相关部分:

let randomColors: [UIColor] = [UIColor.blue,  UIColor.red,  UIColor.yellow,  UIColor.gray]
let obstacleScene = SCNScene(named: "art.scnassets/Scenes/obstacleNormal.scn")
let obstacle = obstacleScene?.rootNode.childNode(withName: "obstacle", recursively: true)

for i in 1...15 {
    let randomPosition = SCNVector3(x: Float(i) * 3.5, y: 0.15, z: sign * Float(arc4random_uniform(UInt32(Int(playgroundZ/2 - 2.0))) + 1))
    let randomColor = randomColors[Int(arc4random_uniform(UInt32(3)))]

    let obstacleCopy = obstacle?.clone()
    obstacleCopy?.position = randomPosition
    obstacleCopy?.geometry?.materials.first?.diffuse.contents = randomColor
    obstacleCopy?.eulerAngles = SCNVector3(x: 10.0 * Float(i), y: Float(30 - i), z: 5.0 * Float(i) * sign) //malo na random

    obstacleCopy?.physicsBody = SCNPhysicsBody(type: .dynamic, shape: nil)
    obstacleCopy?.physicsBody?.isAffectedByGravity = false
    obstacleCopy?.physicsBody?.categoryBitMask = PhysicsCategory.obstacle
    obstacleCopy?.physicsBody?.collisionBitMask = PhysicsCategory.none
    obstacleCopy?.physicsBody?.contactTestBitMask = PhysicsCategory.car1 | PhysicsCategory.car2 | PhysicsCategory.barrier

    obstacleArray.append(obstacleCopy!)
    raceScene!.rootNode.addChildNode(obstacleCopy!)
}
Run Code Online (Sandbox Code Playgroud)

我想在这些对象上设置不同的属性但不能,因为它们的几何是共享的.
我尝试复制对象并克隆它,但我看不出复制或克隆它的任何差异.

是否有可用于实现几何图形去除的属性,类似于场景编辑器中的选项,或者是否还应该复制对象的几何及其材质的方法?

Jam*_*s P 13

根据clone() API参考,您可以在克隆后复制几何体,这将为您的节点创建一个新的非共享几何体.

let newNode = node.clone()
newNode.geometry = node.geometry?.copy() as? SCNGeometry
Run Code Online (Sandbox Code Playgroud)

附加到复制几何体的材质仍与原始材质上使用的材质相同,因此任何更改仍会影响两者.创建新材料或制作副本.

if let newMaterial = newNode.geometry?.materials.first.copy() as? SCNMaterial {
    //make changes to material
    newNode.geometry?.materials = [newMaterial]
}
Run Code Online (Sandbox Code Playgroud)