1

I’m playing around with SpriteKit and GameplayKit. But when I run my code, the sprite I’m expecting to wander around, does nothing.

I used lldb to print out some values, this is the print out:

(lldb) po agentSystem.components
▿ 1 elements
  - [0] : <GKAgent2D: 0x7fc1b8e55ff0>

(lldb) po agentSystem.components
0 elements

The first is printed just after addComponentWithEntity: is called. The second is printed in the update: method.

Of course this must be the reason the sprite does not wander, but what could be causing the problem?

I’ve even looked at and used code from Apple’s sample code for Agents but that still doesn’t seem to fix the issue.

Here is my scene’s code:

import SpriteKit
import GameplayKit

class GameScene: SKScene
{
    //  MARK: - Properties

    let agentSystem = GKComponentSystem(componentClass: GKAgent2D.self)

    var lastUpdateTimeInterval: CFTimeInterval = 0.0


    //  MARK: - Scene Lifecycle

    override func didMoveToView(view: SKView)
    {
        //  Wave enemy
        let agent = GKAgent2D()
        agent.behavior = GKBehavior(goal: GKGoal(toWander: 10), weight: 100)

        let waveEnemy = WaveEnemy()
        waveEnemy.addComponent(agent)

        agentSystem.addComponentWithEntity(waveEnemy)

        let waveSprite = waveEnemy.componentForClass(VisualComponent)!.spriteNode
        waveSprite.position = CGPoint(x: frame.size.width * 0.5, y: frame.size.height * 0.5)

        addChild(waveSprite)
    }

    override func update(currentTime: CFTimeInterval)
    {
        if lastUpdateTimeInterval == 0
        {
            lastUpdateTimeInterval = currentTime
        }

        let deltaTime: CFTimeInterval = currentTime - lastUpdateTimeInterval
        lastUpdateTimeInterval = currentTime

        //  Update component system
        agentSystem.updateWithDeltaTime(deltaTime)
    }
}
Adam Carter
  • 4,741
  • 5
  • 42
  • 103

1 Answers1

4

I had a similar issue. Turns out my GKEntity had a weak reference to it which caused it to automatically get removed from the GKComponentSystem.

In your case you're creating waveEnemy which needs to be held on to. You can store it in an array on the scene.

class GameScene: SKScene {

    ...

    var enemies = [GKEntity]()

    override func didMoveToView(view: SKView) {
        ...
        let waveEnemy = WaveEnemy()
        waveEnemy.addComponent(agent)
        enemies.append(waveEnemy) // Creates a strong reference for waveEnemy
        ...
    }

    ...

}
mikeytdan
  • 254
  • 2
  • 8
  • Yeah this was the fix for me too if I remember correctly - forgot to update the question! Thanks for the reply though :) – Adam Carter Oct 02 '16 at 11:27
  • That's awesome, thank you! PS. Is there a way to debug weak/strong references? – Filip Juncu Jan 21 '17 at 23:29
  • Oh my goodness I've been searching for hours! This totally fixed my game! Thank you very much. Just adding the var enemies = [GKEntity]() line and appending the new entity to create a strong reference was the only thing I was missing. Thank you! – retrovius Jul 02 '17 at 00:49