Scene created in Sprite kit level editor is not working
It may be transition to a grey scene due to spelling errors or the file not even being in the mainBundle. I have tested this and it works. You need to make sure that you are writing the exact name of the .sks file when loading or else you get a grey screen.
Example
If the file is called GameScreen.sks
and the class is called GameScene
then if you put the class name when loading the .sks file you will get a grey screen.
let doors = SKTransition.doorwayWithDuration(1.0)
let archeryScene = GameScene(fileNamed: "GameScreen")
self.view?.presentScene(archeryScene, transition: doors)
So if we look at the second line of code, We see that it is loading the .sks file with the name GameScreen
opposed to the class name GameScene
. We also abort using the file extension because the compiler know by default it is a .sks file we are searching for in the mainBundle.
If you do keep getting a grey screen, Then it may be an error in spelling or ing you GameViewController, In the SKNode Extension, Be sure to change
extension SKNode {
class func unarchiveFromFile(file : NSString) -> SKNode? {
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 GameScene
archiver.finishDecoding()
return scene
} else {
return nil
}
}
}
to this..
extension SKNode {
class func unarchiveFromFile(file : NSString) -> SKNode? {
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 SKScene
archiver.finishDecoding()
return scene
} else {
return nil
}
}
}
We just edited this line of code,
let scene = archiver.decodeObjectForKey(NSKeyedArchiveRootObjectKey) as GameScene
to this
let scene = archiver.decodeObjectForKey(NSKeyedArchiveRootObjectKey) as SKScene
This will allow us to load multiple .sks
files without any errors or crashes.
SpriteKit reference nodes from level editor
you will have to loop through the children of the scene and assign them to local objects to use in your code
assuming your objects in your SKS file were named Obstacle1, Obstacle2, Obstacle3
Once in local objects you can check and do whatever you want with them
let obstacle1 = SKSpriteNode()
let obstacle2 = SKSpriteNode()
let obstacle3 = SKSpriteNode()
let obstacle3Location = CGPointZero
func setUpScene() {
self.enumerateChildNodesWithName("//*") {
node, stop in
if (node.name == "Obstacle1") {
self.obstacle1 = node
}
else if (node.name == "Obstacle2") {
self.obstacle2 = node
}
else if (node.name == "Obstacle3") {
self.obstacle3Location = node.position
}
}
}
Do I need to create a new SpriteKit level editor file for every new .swift file?
Short Answer. Yes.
Reason..
Every time you want to present or load an .sks file, You need to load it with a class like so
let doors = SKTransition.doorwayWithDuration(1.0)
let archeryScene = GameScene(fileNamed: "GameScene")
self.view?.presentScene(archeryScene, transition: doors)
If you look a the constant loads the file with a class
MyScene(fileNamed: "MyScene")
So yeah you do need a .swift file for each .sks file.
For more info on .sks files look here.
Techotopia - An iOS 8 Swift Sprite Kit Level Editor Game Tutorial
Also when I use the Spritekit Level Editor, I usually set the Scene size to 960 x 640 to support the smallest iPhone. Alsong as you have @1x, @2x, @3x
and possibly @1x~iPad
and @2x~iPad
, Everything will be fine. Just to be sure in the ViewDidLoad
or the initWithSize(CGSize)
to add self.scaleMode = .AspectFill.
You can set it to what ever it may be. Your options are,
SKSceneScaleMode.Fill
Each axis of the scene is scaled independently so that each axis in the scene exactly maps to the length of that axis in the view.
SKSceneScaleMode.ResizeFill
The scene is not scaled to match the view. Instead, the scene is automatically resized so that its dimensions always matches those of the view.
SKSceneScaleMode.AspectFit
The scaling factor of each dimension is calculated and the smaller of the two is chosen. Each axis of the scene is scaled by the same scaling factor. This guarantees that the entire scene is visible, but may require letterboxing in the view.
SKSceneScaleMode.AspectFill
The scaling factor of each dimension is calculated and the larger of the two is chosen. Each axis of the scene is scaled by the same scaling factor. This guarantees that the entire area of the view is filled, but may cause parts of the scene to be cropped.
(Credits to @epicbyte - Dealing with different iOS device resolutions in SpriteKit)
Level Editor for Sprite Kit?
Here's a list. In alphabetical order, as of July 5th, 2015:
Available:
- Level Helper 2 apparently supports Sprite Kit (link to docs)
- Sprite Kit Designer is designed specifically for Sprite Kit but has not been updated since April 2014 (possibly discontinued?)
- Xcode has a Sprite Kit Scene Editor built-in (Scene Editor)
Not (yet) available
- SpriteBuilder v1.1 beta had experimental support for Sprite Kit (w/o physics) but this feature was dropped.
If you know a Sprite Kit (or compatible) visual design tool that's not listed here please add it as a comment. I will update the list infrequently.
Unarchived Node doesn't appear when added to parent in SpriteKit
The problem wasn't whether or not Loaded it as an unarchived file or if I loaded it as a SKReferenceNode. Although after finding out about and researching this SKReferenceNode is EXACTLY the way to go and was probably made for this purpose.
The problem was that in the scene editor the custom object was positioned beside the scene (x = -1500) because when I originally constructed it was in the scene.sks file and I didn't want it on top of the scene objects. when I transferred it to it's own sks file it kept it's positioning. I didn't think that this was a big deal because after I loaded the sks file into a variable I set it's position to CGPoint(x: 0, y: 0) in code. The problem is that you CANNOT move the loaded scene object around the existing scene, so if it is off screen it will stay offscreen. Setting the position did nothing, and it didn't matter if it was an unarchived file or SKReferenceNode it wouldn't move.
So i referenced the first child in the sks file and set it's position and viola!
If anyone is interested at what can be done with this setup, you can create and layout complex custom objects in their own sks file and then load them into your scene file. The beauty of doing it this way is that your sks files don't become cluttered and then your custom object sks's can be reference in multiple different scenes.
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)
}
Related Topics
Spritekit - Create at Random Position Without Overlapping
Get Larger Facebook Image Through Firebase Login
Not Condition in 'If Case' Statement
Subclass.Fetchrequest() Swift 3.0, Extension Not Really Helping 100%
"Ambiguous Use of 'Propertyname'" Error Given Overridden Property with Didset Observer
What Does <> (Angle Brackets) Do on Class Names in Swift
How to Set a Specific Default Time for a Date Picker in Swift
Swift Mkmapview Drop a Pin Annotation to Current Location
Swift 3:Fatal Error: Double Value Cannot Be Converted to Int Because It Is Either Infinite or Nan
Skip Item When Performing Map in Swift
How Use and Run Swift 2.3 on Command Line
Which Swift Character Count Should I Use When Interacting with Nsstring APIs
How to Store a Reference to an Integer in Swift
Why Can't I Pass an Implicitly Unwrapped Optional as an Unsafemutablepointer
Can't Parse JSON Array with JSONdecoder in Swift 4
Swiftui - Foreach Deletion Transition Always Applied to Last Item Only