SpriteKit unarchiveFromFile 不会从资产目录和图集中加载纹理

SpriteKit unarchiveFromFile does not load textures from asset catalogues and atlases

我对 SpriteKit 还是个新手,想看看我是否可以使用 Xcode 的 SKS 编辑器构建关卡。当我添加几个带有 "Spaceship.png" 纹理的精灵并构建模板应用程序时,纹理不会加载。

这是原版 OSX 游戏模板的屏幕截图,使用 Swift 作为语言,并添加了提供的 "Spaceship.png" 精灵。纹理显示良好: 这是仅对模板进行修改后构建和 运行 应用程序的结果:

调试控制台显示此警告消息: 我尝试添加一个 .atlas 文件夹,结果相同。场景只显示红色 X 图标代替精灵。如果添加的精灵只是彩色精灵,它们显示良好。前段时间我废弃了一个应用程序,我曾经在其中加载 SKScene 并将精灵资产手动添加到我的 SKScene 子 class,并且运行良好。

但是,如果我将纹理 - "Spaceship.png" 作为示例 - 移动到项目的根目录,即不在资产目录或 .atlas 文件夹中,场景加载时纹理显示良好。

这是添加到项目根目录的纹理:

这是期望的结果: 我尝试通过 enumerateChildNodesWithName(_,usingBlock) 手动将 SKS 文件中加载的资源添加到场景中,如果纹理不在项目文件夹的根目录中,我会得到相同的结果。

这是我尝试手动添加资产:

    func applicationDidFinishLaunching(aNotification: NSNotification) {
    /* Pick a size for the scene */
    if let scene = GameScene.unarchiveFromFile("GameScene") as? GameScene {
        let sceneToBePresented = GameScene()

        /* Set the scale mode to scale to fit the window */
        sceneToBePresented.scaleMode = .AspectFill
        sceneToBePresented.size = scene.size

        /* Sprite Kit applies additional optimizations to improve rendering performance */
        self.skView!.ignoresSiblingOrder = true

        self.skView!.showsFPS = true
        self.skView!.showsNodeCount = true
        scene.enumerateChildNodesWithName("*") { node, stop in
            sceneToBePresented.addChild(node.copy() as SKSpriteNode)
        }

        self.skView!.presentScene(sceneToBePresented)
    }
}

我环顾了 SpriteKit classes - SKNodeSKSceneSKTextureSKSPriteNode - 寻找关于路径、缓存、预加载的任何线索,或任何东西,但无法找到可以使这项工作成功的东西。

我是 运行 Xcode 6.1.1,我的目标是 10.9,我使用的语言是 Swift,尽管使用 ObjC 也是如此。这是功能还是错误?还有其他人 running/ran 遇到类似情况吗?

提前感谢您的帮助

[更新]

看起来这还没有实现 - 从资产目录加载纹理 - 因为这个 post 在开发论坛中讨论了同样的问题,他的解决方案是将资产目录重命名为与质地。本质上,我发现根文件夹中有图像文件:How do you load sprite textures from Images.xcassets when using SKS scene file,尽管我设法回滚到工作状态的早期应用程序确实从 .atlas'es 加载纹理,但我可以似乎用一个干净的模板来做!!!

[在这里回答我自己的问题]

据我所知,目前,从资产目录加载纹理 - Images.xcassets - 而取消存档或反序列化 SKScene 文件在 OSX 上不起作用我的尝试和上面提到的 devforumns post。

然而,从图像集加载纹理是通过强制 SKTexture 加载图像来实现的。可以通过 preloadWithCompletionHandler(_:)preloadTextures(_:, withCompletionHandler:) 方法强制或“触摸”SKTexture,或者正如我所发现的,只需打印精灵 SKTexture 的描述即可。

为了任何可能需要进一步帮助的人的利益,这里是一个代码片段,它在解压缩 SKS 文件后预加载纹理:

if let scene = GameScene.unarchiveFromFile("GameScene") as? GameScene {
    for child in scene.children as [SKNode] {
        if child is SKSpriteNode {
            let sprite = child as SKSpriteNode
            sprite.texture?.preloadWithCompletionHandler({ })
            /* or even a simple debug log of the texture */
            /* println(sprite.texture) */
        }
    }
    /* Do your other stuff ... */
    ...
}

如有错误请指正。在有人这样做之前,或者 Apple 修复了 SpriteKit 在 iOS 和 OSX 之间的行为之间的差异,我不会寻找其他解决方案,并将遵循墨菲定律:

If it works, don't fix it

遵循 Salam Horani 的解决方案,对于 Swift 2.x 你还没有 "unarchiveFromFile" 所以你可以创建这样的场景:

if let gameScene = GameScene(fileNamed: "GameScene") {
    // ...
}