无法强制转换类型为"SKScene"的值



我创建了一个新的Xcode Game项目。我去掉了项目中的默认动画,并添加了一个新的Swift文件和一个新的。sks文件,它们都叫MenuScene。

在我的GameViewController中,我用MenuScene替换了GameScene的引用,因为我想让这个场景首先启动:

override func viewDidLoad() {
    super.viewDidLoad()
    // Load 'GameScene.sks' as a GKScene. This provides gameplay related content
    // including entities and graphs.
    if let scene = GKScene(fileNamed: "MenuScene") {
        // Get the SKScene from the loaded GKScene
        if let sceneNode = scene.rootNode as! MenuScene? {
            // Set the scale mode to scale to fit the window
            sceneNode.scaleMode = .aspectFill
            // Present the scene
            if let view = self.view as! SKView? {
                view.presentScene(sceneNode)
                view.ignoresSiblingOrder = true
                view.showsFPS = true
                view.showsNodeCount = true
            }
        }
    }
}

当我尝试启动我得到以下错误:

Could not cast value of type 'SKScene' (0x1105624) to 'Spritekit10.MenuScene' (0x104c38).

如果我将其更改回GameScene,它似乎具有完全相同的设置,一切似乎都很好。

谁能给我指出正确的方向,问题是什么?

在我的MenuScene.sks下自定义类,我已经添加了MenuScene认为这是问题,但错误仍然显示(和文本字段似乎随机清除自己,当我回到它。

import SpriteKit
import GameplayKit
class GameScene: SKScene {
    override func sceneDidLoad() {
    }
}

.

import SpriteKit
import GameplayKit
class MenuScene: SKScene {
    override func sceneDidLoad() {
    }
}

我明白了。

对于。sks文件,我必须在属性检查器中为场景添加一个名称(即使它在GameScene中是空白的)。一旦我这样做了,自定义类的值就保存下来了,文件现在就载入了,没有任何错误。不知道这是bug还是故意的

您的问题是您正在尝试将SKScene上推到MenuScene。

这是不能做到的,我看到你已经检查了你的自定义类在你的任务文件,以确保它被设置为MenuScene,但你确保你保存它正确吗?你需要输入它并按回车键,如果你不这样做,那么场景将不会自动保存它,当你离开时将清除它。

对于Xcode 8.0/8.1,创建一个名为"Menuscene"的swift文件和一个名为"Menuscene"的sks文件。删除Menuscene swift文件中的所有内容,并插入以下代码

import SpriteKit
import GameplayKit
class Menuscene: SKScene {
override func didMove(to view: SKView) {
    let menutext = SKLabelNode()
    menutext.text = "MEnuscene"
    menutext.position = CGPoint(x: 0, y: 0)
    menutext.fontSize = 120
    self.backgroundColor = UIColor.blue
    addChild(menutext)
}

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    let gamescene = SKScene(fileNamed: "GameScene")
    gamescene?.scaleMode = .fill
    self.scene?.view?.presentScene(gamescene!,transition: SKTransition.doorsCloseHorizontal(withDuration: 1.0))
}
override func update(_ currentTime: TimeInterval) {
  }
}

,在属性检查器选项卡中,将名称设置为"Menuscene",按回车键(非常重要)。然后在下一个选项卡中,将自定义类名称设置为"Menuscene",按回车键(非常重要)。

在你的Gamescene.swift文件中,仔细检查你的类是否以 开头。
class GameScene: SKScene {

将这段代码添加到你的touchesBegan函数

   override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    let Menuscene = SKScene(fileNamed: "Menuscene")
    Menuscene?.scaleMode = .fill
    self.scene?.view?.presentScene(Menuscene!,transition: SKTransition.doorsOpenVertical(withDuration: 1.0))
    }

最后在你的Gameviewcontroller文件中,删除所有内容并插入以下代码

import UIKit
import SpriteKit
import GameplayKit
class GameViewController: UIViewController {
override func viewDidLoad() {
    super.viewDidLoad()
    if let view = self.view as! SKView? {
        // Load the SKScene from 'GameScene.sks'
        if let scene = SKScene(fileNamed: "Menuscene") {
            // Set the scale mode to scale to fit the window
            scene.scaleMode = .aspectFill
            // Present the scene
            view.presentScene(scene)
        }
        view.ignoresSiblingOrder = true
        view.showsFPS = true
        view.showsNodeCount = true
    }
}
override var shouldAutorotate: Bool {
    return true
}
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
    if UIDevice.current.userInterfaceIdiom == .phone {
        return .allButUpsideDown
    } else {
        return .all
    }
}
override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Release any cached data, images, etc that aren't in use.
}
override var prefersStatusBarHidden: Bool {
    return true
}
}

欢迎你!你应该能够从游戏界面点击到菜单界面。

我发现了一些奇怪的事情。我的项目名称有一个"-"字符。在我从目标名称中删除这个角色后,项目可以投射场景。

我可以在iOS 10.3.1上运行

override func viewDidLoad() {
    super.viewDidLoad()
    let fileName = "GameScene"
    // Load 'GameScene.sks' as a GKScene. This provides gameplay related content
    // including entities and graphs.
    guard let scene = GKScene(fileNamed: fileName) else {
        return
    }
    guard let sceneNode = scene.rootNode as? GameScene ?? GameScene(fileNamed: fileName) else {
        return
    }
    // Copy gameplay related content over to the scene
    sceneNode.entities = scene.entities
    sceneNode.graphs = scene.graphs
    // Set the scale mode to scale to fit the window
    sceneNode.scaleMode = .aspectFill
    // Present the scene
    if let view = self.view as! SKView? {
        view.presentScene(sceneNode)
        view.ignoresSiblingOrder = true
        view.showsFPS = true
        view.showsNodeCount = true
    }
}

最新更新