How to pass a string to a SKLabelNode in a SKScene(filenamed:) animation file?

137 views Asked by At

Previously, I passed properties into my SKScene by creating initializers in my SKScene, then setting those initializers when i create my SKScene property in my SceneEditViewController. Did that make sense? I hope so.

However, instead of creating an SKScene manually, I am now using Scene Editor. My animation scene has a SKLabelNode and i want to pass text received from a different viewController into the SKScene's SKLabelNode. Below i provided my previous method in the "if" portion of my if-else. In the "else" portion, i'm attempting the new method but need help.

When trying to set a property from my SKScene, xcode states, "Value of type 'SKScene' has no member 'selectedTextSceneUse1'"

Included below:

  • SceneEditViewController
  • Extension enabling me to receive a text string from another viewController
  • GameScene.swift (swift file connected to my GameScene.sks)

I'm using swift 5.0, please let me know if you need additional information.

import UIKit
import Foundation
import SpriteKit
import GameplayKit

class SceneEditViewController: UIViewController, UITabBarControllerDelegate {

var selectedSceneTextFinal: String?

if selectedSceneInt == 0 {
            let animationScene3 = AnimationInventory18(size: CGSize(width:animationScreen.bounds.width, height:animationScreen.bounds.height), chosenChateracterSceneUse: chosenCharacterFinal, selectedTextSceneUse: selectedSceneTextFinal, chosenBackgroundSceneUse: chosenBackgroundFinal)
            
            animationScene3.scaleMode = .aspectFit
            animationScene3.backgroundColor = .black
            animationScene3.anchorPoint = CGPoint(x: 0.5, y: 0.52)
            animationScene3.position = CGPoint(x: 0, y: 0)
            let transition = SKTransition.fade(withDuration: 1.0)
            animationScreen.presentScene(animationScene3, transition: transition)
            
            DispatchQueue.main.asyncAfter(deadline: .now() + 20){
                self.animationScreen.presentScene(nil)
                print("Scene Removed")
            }
        } else {
     
            if let scene = SKScene(fileNamed: "GameScene") as GameScene {
           
                scene.scaleMode = .aspectFit 
                
                scene.selectedTextSceneUse1 = selectedSceneTextFinal

                animationScreen.presentScene(scene)

                DispatchQueue.main.asyncAfter(deadline: .now() + 10){
                    self.animationScreen.presentScene(nil)
                    print("Scene Removed")
                }
            }
        }
    }

extension SceneEditViewController: textUpdateDelegate {
    func didUpdateText(textFromView: String){
        selectedSceneTextFinal = textFromView
    }
}


import SpriteKit
import GameplayKit

class GameScene: SKScene {
    
    var textNode: SKLabelNode?
    
   // Not receiving the value passed from selectedSceneTextFinal
   var selectedTextSceneUse1: String?
    

    // MARK: Camera Node
    let cameraNode = SKCameraNode()
    
    // Initializer 
     required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    func check() {
        
        self.camera = cameraNode
        cameraNode.position = CGPoint(x: 0, y: -300)
        self.addChild(cameraNode)
        print(selectedTextSceneUse1)


        self.textNode?.text = selectedTextSceneUse1


    }
    
    override func sceneDidLoad() {

        self.lastUpdateTime = 0
        check()
    }

}


1

There are 1 answers

15
Ptit Xav On BEST ANSWER

You should cast your SKScene :

if let scene = SKScene(fileNamed: "GameScene") as? GameScene {

In these cases, as you get GameScene from file you need to implement the init?(coder..) :

required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
}

Be sure to also setup the class type of the scene in the sks file. (custom class inspector)

If you want to setup sklabelnode text hen it change you could add observer on selectedSceneTextFinal :

class SceneEditViewController: UIViewController, UITabBarControllerDelegate {

   var gameScene : GameScene?
   var selectedSceneTextFinal: String? {
       didSet {
           // Update gameScene value when controller value is changed
           gameScene?.selectedTextSceneUse1 = selectedSceneTextFinal
       }
   }
...

        if let scene = SKScene(fileNamed: "GameScene") as GameScene {
            gameScene = scene
            scene.scaleMode = .aspectFit 
            scene.selectedTextSceneUse1 = selectedSceneTextFinal
...


class GameScene: SKScene {

    var textNode: SKLabelNode?

   // Update textNode on update of selectedTextSceneUse1
   var selectedTextSceneUse1: String? {
       didSet {
           // If nit done initialise textNode from sks file (label node must have a name)
           if textNode == nil {
               textNode = childNode(withName: "name of LabelNode in sks file") as? SKLabelNode
           }
           textNode?.text = selectedTextSceneUse1
       }
   }