Добавление SCNNode несколько раз показывает только один раз - PullRequest
0 голосов
/ 29 апреля 2018

Я пытаюсь добавить несколько раз SCNNode в цикле в другой позиции, но я могу видеть один и тот же тип узла сразу с последней позицией.

Ниже приведен код

let entityArray:[entity] = [.coin, .coin, .coin, .brick, .coin, .coin, .coin, .brick]

func setupworld() {
    let scene = SCNScene(named: "art.scnassets/MainScene.scn")!

    var zPosition = -10
    var count = 0
    let delta = -4

    for entity in entityArray {

        var node = SCNNode()

        switch entity {
        case .coin:
            node = scene.rootNode.childNode(withName: "coin", recursively: true) ?? node
            node.position = SCNVector3(0, -5, zPosition)

        case .brick:
            node = scene.rootNode.childNode(withName: "brick", recursively: true) ?? node
            node.position = SCNVector3(0, 0, zPosition)
        }

        self.sceneView.scene.rootNode.addChildNode(node)

        zPosition += delta
        count += 1
    }
}

Показывает одну монету и один кирпич в последних позициях.

Я новичок в scenekit, поэтому буду делать что-то не так, пожалуйста, помогите мне.

1 Ответ

0 голосов
/ 29 апреля 2018

Основываясь на других комментариях и, как сказал @rmaddy, SCNNode имеет функцию clone() (это подход, который вы должны использовать здесь) и который просто:

Создает копию узла и его дочерних элементов.

Однако при использовании этого следует помнить, что каждый cloned Node будет иметь одинаковую геометрию и материалы.

То есть, если бы вы хотели, чтобы в какой-то момент были какие-то кирпичи красного цвета, а некоторые зеленого цвета, вы бы не смогли сделать это этим методом, поскольку:

изменения в объектах, прикрепленных к одному узлу, будут влиять другие узлы с одинаковыми вложениями.

Для этого, например, Чтобы отобразить две копии узла с использованием разных материалов, вы должны скопировать как узел, так и его геометрию, прежде чем назначать новый материал, о котором вы можете прочитать подробнее здесь: Обсуждение Apple

Причина, по которой вы видите только один экземпляр монеты или кирпича, заключается в том, что каждый раз, когда вы повторяете цикл, вы говорите, что вновь созданный узел равен монете или кирпичу, поэтому, естественно, последний элемент в этом цикле будет ссылаться на этот элемент из вашей сцены.

Если применить это на практике и решить вашу проблему, ваш setupWorld function должен выглядеть примерно так:

/// Sets Up The Coins & Bricks
func setupworld(){

    //1. Get Our SCNScene
    guard let scene = SCNScene(named: "art.scnassets/MainScene.scn") else { return }

    //2. Store The ZPosition
    var zPosition =  -10

    //3. Store The Delta
    let delta = -4

    //4. Get The SCNNodes We Wish To Clone
    guard let validCoin = scene.rootNode.childNode(withName: "coin", recursively: true),
           let validBrick = scene.rootNode.childNode(withName: "brick", recursively: true) else { return }

    //5. Loop Through The Entity Array & Create Our Nodes Dynamically
    var count = 0

    for entity in entityArray {

        var node = SCNNode()

        switch entity{

        case .coin:
            //Clone The Coin Node
            node = validCoin.clone()
            node.position = SCNVector3(0, -5, zPosition)

        case .brick:
            //Clone The Brick Node
            node = validBrick.clone()
            node.position = SCNVector3(0, 0, zPosition)
        }

        //6. Add It To The Scene
        self.sceneView.scene.rootNode.addChildNode(node)

        //7. Adjust The zPosition
        zPosition += delta
        count += 1
    }

}
...