添加到SpriteKit中的父项时,未存档的节点不会显示

以前我一直在质疑是否可以使用场景编辑器创build复杂的SKSpriteNodes,而不是使用它来布局SKScenes。 在@Anton Rogachevskyi的帮助下,我开始使用unarchiveNodeFromFilefind.SKS文件。 它会像我所期望的那样加载sks文件,但是当我尝试将它添加到当前场景时,不会出现任何内容。 如果我在addChild行中断,并预览正确显示在预览窗口中的对象,所以我知道它find了正确的文件。 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) } } 

而在场景中,这是我如何find对象,并尝试将其添加到场景,它出现在预览中,但没有显示在屏幕上

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

打破对象的预览

再次,我可以在预览窗口中看到它,但是当它被添加到场景中时什么也不会显示。

我是否必须处理一个已经被取消存档的对象,或者在我能将其添加到场景之前做一些事情?

我把代码拉出来,把它放在一个testing项目中,得到了相同的结果。

我已经尝试添加sks文件(作为节点)到现场没有运气,我试图从sks文件中隔离出对话框,并添加它没有运气

问题不在于是否将其加载为未归档的文件,或者是否将其作为SKReferenceNode加载。 虽然在了解和研究这个SKReferenceNode之后是完全可行的,可能是为了这个目的。

问题是在场景编辑器中,自定义对象被放置在场景(x = -1500)旁边,因为当我最初构build它时,它在scene.sks文件中,我不希望它在场景对象的顶部。 当我把它转移到它自己的sks文件时,它保持了它的定位。 我不认为这是一个大问题,因为在我把sks文件加载到一个variables后,我把它设置为代码中的CGPoint(x:0,y:0)。 问题是你不能移动现有场景周围的加载场景对象,所以如果它在屏幕外,它将保持离屏。 设置位置什么都不做,它是否是一个unarchived文件或SKReferenceNode它不会移动没关系。

所以我引用sks文件中的第一个孩子,并设置它的位置和中提琴!

如果有人对此设置可以做什么感兴趣,可以在自己的sks文件中创build和布局复杂的自定义对象,然后将它们加载到场景文件中。 这样做的美妙之处在于,您的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) }