Discoveringmypath Discoveringmypath - 3 years ago 171
Swift Question

how to access entity from code - gameplay kit

I have a node I added in the scene. Also in the scene I give it a component to bounce. The component looks like this:

class BounceComponent: GKComponent, ComponentSetupProt {

var bounce: SKAction?
var node: SKSpriteNode?

@GKInspectable var diff: CGFloat = 0.2
@GKInspectable var startScale: CGFloat = 1
@GKInspectable var duration: TimeInterval = 0.5

override init() {

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

func setup() {
node = entity?.component(ofType: GKSKNodeComponent.self)!.node as? SKSpriteNode

func setupBounce() {

func performBounce() {

In the didMove function on my scene file, it calls the components setup(). This works fine. I'm trying to call the function performBounce() when I click on the button...

if (play?.contains(pos))! {
if let _ = play?.entity {
print("we have an entity")
play?.entity?.component(ofType: BounceComponent.self)?.performBounce()

When I click, the only thing it prints is "test" and the entity is nil. I was under the assumption that when you add a node to the editor, it also sets up the entity for that node, so I'm not sure why it is nil. Curious if anyone could shed some light on this?

Thanks for any help!

Answer Source

The entity on the SKSpriteNode is a weak reference, you need to make sure you retain your entities from your gameplaykit object

class GameViewController: UIViewController {

    override func viewDidLoad() {

        // Load 'GameScene.sks' as a GKScene. This provides gameplay related content
        // including entities and graphs.
        if let scene = GKScene(fileNamed: "Main") {

            // Get the SKScene from the loaded GKScene
            if let sceneNode = scene.rootNode as? Main {

                sceneNode.entities = scene.entities // add this

                // Set the scale mode to scale to fit the window
                sceneNode.scaleMode = .aspectFill

                // Present the scene
                if let view = self.view as! SKView? {
                    view.showsDrawCount = true
                    view.ignoresSiblingOrder = true
                    view.showsFPS = true
                    view.showsNodeCount = true

class Main: Base {
    var entities = [GKEntity]() // add this
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download