2017-01-30 2 views
3

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

dialog being created in the scene editor

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

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 
    } 
} 

break preview of the object

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

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

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

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

+1

Эти вопросы являются блестящими. Весь другой уровень тщательности и интересный сам по себе. – Confused

+0

Спасибо, я ценю это.Я нахожусь в точке с SpriteKit, что мне нужно начать получать больше функциональности из-за этого, потому что ожидая, что Apple активирует функции или поддержку, кажется, это потерянная причина. –

+0

Из памяти iOS от 8 до 9 обнаружено больше ошибок, чем функций, добавленных в SpriteKit. В iOS 10 добавлена ​​трава, размахивающая SKWarpNode и еще что-то, что я забыл. Хотя это было, конечно, удивительно _ **. – Confused

ответ

2

Проблема WASN Не загружен ли он как файл с открытием или если я загрузил его как 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) 
    }