I'm trying to make a gamescene whith multiple layers of spritenodes persistent so that after you press start into the welcome screen, the last saved state of the gamescene gets loaded. I wrote encode/decode methods in the custom classes that i initialize in didMove() and i used nskeyedarchiver to save the gamescene, but when it is loaded all the variables of the scene are set to nil. The buttons show up and work, but they are not linked to the scene, and they all result nil into the debugger, so anything that i'm trying to do into the scene after loading results in a crash. How should i change the code to make it work?
Gamescene
override func didMove(to view: SKView)
{
UNUserNotificationCenter.current().delegate = self
let data = UserDefaults.standard.object(forKey: "bool") as? Bool
if data == false || data == nil
{
NotificationCenter.default.addObserver(self, selector: #selector(Save), name: .Save, object: nil)
UserDefaults.standard.set(true, forKey: "bool")
gameVC?.currentScene = self
let randomPlanetSize = Int.random(in: 160...240)
planet = self.generateWorld(worldTexture: "planet1", position: nil, size: CGSize(width: randomPlanetSize, height: randomPlanetSize), rotationDuration: 300)
planet.zPosition=10
planet.isUserInteractionEnabled=true
self.addChild(planet)
....
backButton = ReturnButton(texture: SKTexture(image: #imageLiteral(resourceName: "backButton2")), color: .white, size: CGSize(width: 60, height: 30),scene: self,position: CGPoint(x: 50, y: frame.height-80),initpos: CGPoint(x: 50, y: frame.height-80),zpos: 10)
self.addChild(backButton!)
}
else
{
backButton?.isUserInteractionEnabled = true
}
}
Return Button
class ReturnButton: SKSpriteNode {
var scena: Main_GameScene
var initialPosition = CGPoint()
var goback = false
init(texture: SKTexture?, color: UIColor, size: CGSize, scene: Main_GameScene, position: CGPoint,initpos: CGPoint,zpos: CGFloat) {
self.scena = scene
self.initialPosition = initpos
super.init(texture: texture, color: color, size: size)
self.position = position
self.zPosition = zpos
self.isUserInteractionEnabled = true
self.colorBlendFactor = 1
}
required convenience init?(coder aDecoder: NSCoder) {
let scena = aDecoder.decodeObject(forKey: "scenareturn") as! Main_GameScene
let color = aDecoder.decodeObject(forKey: "coloreturn") as! UIColor
let size = aDecoder.decodeCGSize(forKey: "sizereturn")
let text = aDecoder.decodeObject(forKey: "textureturn") as! SKTexture
let pos = aDecoder.decodeCGPoint(forKey: "positionreturn")
let initpos = aDecoder.decodeCGPoint(forKey: "initpositionreturn")
let zpos = aDecoder.decodeObject(forKey: "zposreturn") as! CGFloat
self.init(texture: text, color: color, size: size,scene: scena,position: pos, initpos: initpos, zpos: zpos)
}
override func encode(with aCoder: NSCoder) {
aCoder.encode(self.texture, forKey: "textureturn")
aCoder.encode(self.scena, forKey: "scenareturn")
aCoder.encode(self.color, forKey: "coloreturn")
aCoder.encode(self.size, forKey: "sizereturn")
aCoder.encode(self.position, forKey: "positionreturn")
aCoder.encode(self.initialPosition, forKey:"initpositionreturn")
aCoder.encode(self.zPosition, forKey:"zposreturn")
}
...
Game view controller
if let data = UserDefaults.standard.object(forKey: "scene") as? Data {
let scene = NSKeyedUnarchiver.unarchiveObject(with: data) as! Main_GameScene
let view = self.view as! SKView?
scene.gameVC=self
view!.allowsTransparency = true
view!.backgroundColor = .clear
scene.backgroundColor = .clear
scene.scaleMode = .resizeFill
view!.ignoresSiblingOrder = false
view!.showsFPS = true
view!.showsNodeCount = false
view!.presentScene(scene)
}