Unarchived Node не появляется при добавлении родителя в SpriteKit

Раньше я спрашивал, могу ли я использовать редактор Scene для создания сложных SKSpriteNodes и просто использовать его для компоновки SKScenes. С помощью @Anton Rogachevskyi предыдущего вопроса я начал использовать unarchiveNodeFromFile для поиска файла .SKS. Он загружает файл sks, как и следовало ожидать, но когда я пытаюсь добавить его в текущую сцену, ничего не появляется. Если я сломаю строку addChild и просмотрю объект, который он отобразит в окне предварительного просмотра, поэтому я знаю, что он находит правильный файл. Внутри файла sks есть пользовательский класс диалога и установка контрольных точек в "требуемом init?" (Coder aDecoder: NSCoder) "Я могу сказать, что пользовательский объект получает правильную инициализацию.

диалог, созданный в редакторе сцен

внутри класса диалога я программно добавляю розовое поле к объекту, чтобы показать, что он достигает init класса

class TeamDialog: SKSpriteNode {

init(size: CGSize) {
    super.init(texture: nil, color: .red, size: size)
}

required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)

    setup()
}

func setup() {

    let pinkBox = SKSpriteNode(color: .magenta, size: CGSize(width: 100, height: 100))
    pinkBox.zPosition = 500
    addChild(pinkBox)
}
}

И в Сцене это то, как я нахожу объект и пытаюсь добавить его в сцену, он появляется в предварительном просмотре, но ничего не отображается на экране

private func displayDialog() {

    if let wtf = unarchiveNodeFromFile(file: "TeamDialog")! as SKNode? {

        let layer = SKSpriteNode(color: .clear, size: self.size)
        layer.zPosition = 5000
        layer.position = CGPoint(x: self.size.width / 2, y: self.size.height / 2)
        addChild(layer)

        for child in wtf.children {
            print("child \(child.name)")
            if let teamDialog = child as? TeamDialog {
                teamDialog.removeFromParent()
                layer.zPosition = 1
                layer.addChild(teamDialog)
            } 
        }
    }
}

func unarchiveNodeFromFile(file: String) -> SKNode? {

    if let path = Bundle.main.path(forResource: file, ofType: "sks") {

        let fileData = NSData.init(contentsOfFile: path)
        let archiver = NSKeyedUnarchiver.init(forReadingWith: fileData as Data!)
        archiver.setClass(SKNode.classForKeyedUnarchiver(), forClassName: "SKScene")
        let node = archiver.decodeObject(forKey: NSKeyedArchiveRootObjectKey) as! SKNode
        archiver.finishDecoding()
        return node
    } else {
        return nil
    }
}

предварительный просмотр объекта

Опять же, я вижу это в окне предварительного просмотра, но ничего не появляется, когда он добавляется в сцену.

Должен ли я обрабатывать объект, который был разрхивирован по-другому или что-то делать, прежде чем я могу добавить его в сцену?

Я вытащил код и поместил его в тестовый проект с теми же результатами.

Я попытался добавить файл sks (как node) на сцену без везения, и я попытался изолировать диалог из файла sks и добавить его без везения

+3
источник поделиться
1 ответ

Проблема заключалась не в том, загружалась ли она как в файл с открытыми файлами, либо загружалась ли она как SKReferenceNode. Хотя выяснение и исследование этого SKReferenceNode является ТОЧНО, как это сделать, и, вероятно, было сделано для этой цели.

Проблема заключалась в том, что в редакторе сцены пользовательский объект располагался рядом с сценой (x = -1500), потому что когда я изначально был создан, он находился в файле scene.sks, и я не хотел, чтобы он был поверх сцены объекты. когда я передал ему собственный файл sks, он сохранил его позиционирование. Я не думал, что это было большим делом, потому что после того, как я загрузил файл sks в переменную, я установил его положение в CGPoint (x: 0, y: 0) в коде. Проблема заключается в том, что вы НЕ МОЖЕТЕ перемещать загруженный объект сцены вокруг существующей сцены, поэтому, если он выключен, он останется на экране. Установка положения ничего не делала, и неважно, был ли это файл с сохраненным архивом или SKReferenceNode, он не двигался.

Итак, я обратился к первому ребенку в файле sks и установил его положение и альта!

Если кто-то заинтересован в том, что можно сделать с помощью этой установки, вы можете создавать и компоновать сложные пользовательские объекты в своем собственном файле sks, а затем загружать их в файл сцены. Красота делает это таким образом, что ваши файлы sks не становятся загроможденными, а затем ваш пользовательский объект sks может быть ссылкой в ​​нескольких разных сценах.

    let path = Bundle.main.path(forResource: "TeamDialog", ofType: "sks")
    let dialogScene = SKReferenceNode (url: URL (fileURLWithPath: path!))
    if let teamDialog = dialogScene.childNode(withName: "//teamDialog") as? TeamDialog {
        teamDialog.setup(scene: self)
        teamDialog.position = CGPoint(x: 0, y: 0)
        dialogScene.zPosition = 5000
        addChild(dialogScene)
    }
+2
источник

Связанные вопросы


Похожие вопросы

Посмотрите другие вопросы по меткам или Задайте вопрос