What is the method unarchiveFromFile in GameViewCo

2019-05-05 17:25发布

问题:

When I tried to add different scenes to my game in Swift, I encountered the method unarchiveFromFile. The problem with this method is that it only works with the GameScene class. If you call it from

extension SKNode {
    class func unarchiveFromFile(file : NSString) -> SKNode? {
        if let path = NSBundle.mainBundle().pathForResource(file, ofType: "sks") {
            var sceneData = NSData.dataWithContentsOfFile(path, options: .DataReadingMappedIfSafe, error: nil)
            var archiver = NSKeyedUnarchiver(forReadingWithData: sceneData)

            archiver.setClass(self.classForKeyedUnarchiver(), forClassName: "SKScene")
            let scene = archiver.decodeObjectForKey(NSKeyedArchiveRootObjectKey) as GameScene 
            archiver.finishDecoding()
            return scene
        } else {
            return nil
        }
    }
}

class GameViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        if let scene = GameScene.unarchiveFromFile("GameScene") as? GameScene {
             let skView = self.view as SKView
             skView.ignoresSiblingOrder = true
             skView.presentScene(scene)
        }
        // This won't work for MenuScene.unarchiveFromFile("MenuScene") as? MenuScene
        // nor MenuScene.unarchiveFromFile("MenuScene") as? GameScene

To be able to work with other SKScenes I changed all occurrences of the class GameScene to SKScene. While it now works with other SKScene classes I still don't understand what it is.

What is it this method for? should I keep it?

回答1:

I haven't used Xcode 6 much, but here is my understanding (someone may correct me or expound) :

This is how your app utilizes the layout data etc for the GameScene (or any SKScene). If you click on the GameScene.sks file in the Project Navigator panel you get a visual editor for your GameScene.

If you want this layout data to be utilized, you would use that method. You can visually layout your GameScene in the scene editor without need to code locations, settings etc.



回答2:

Following on from 0x141E's comment, you can change the unarchiveFromFile method to use generics so you can use it for different SKS or SKScene classes:

extension SKNode {
    class func unarchiveFromFile<T:SKScene>(file : NSString) -> T? {
        if let path = NSBundle.mainBundle().pathForResource(file, ofType: "sks") {
            var sceneData = NSData(contentsOfFile: path, options: .DataReadingMappedIfSafe, error: nil)!
            var archiver = NSKeyedUnarchiver(forReadingWithData: sceneData)

            archiver.setClass(self.classForKeyedUnarchiver(), forClassName: "SKScene")
            let scene = archiver.decodeObjectForKey(NSKeyedArchiveRootObjectKey) as T
            archiver.finishDecoding()
            return scene
        } else {
            return nil
        }
    }
}

Just call it the same way but with the different scene content you want in there and it should work fine

if let scene = GameScene.unarchiveFromFile("Level1Scene") as? GameScene {
...

if let scene = GameScene.unarchiveFromFile("Level2Scene") as? GameScene {
...