Search code examples
swiftsprite-kitgameplay-kit

How can I animate a moving GKAgent2D with a goal in Swift using Spritekit and GameplayKit?


I am building a game in Swift using Spritekit and GameplayKit. I am currently having trouble animating the AI-enemy that competes against the player.

In the game, players collect falling objects from the sky which they use to plant flowers. The human controlled players animation is simple, I move left and right via a joystick and trigger a different SKAction for the animation while the joystick's X position is +/-.

But for the enemy, their movement is automatic based on GKGoals and they are constantly jumping and moving left and right. What is the proper way to trigger animations for moving agent? Currently I try to react based on the agent's velocity (+/- dx) in the agentWillUpdate function

func agentWillUpdate(_ agent: GKAgent) {
    if let agent = agent as? GKAgent2D  {
        agent.position = float2(Float((node.position.x)), Float((node.position.y)))
    }
    guard let aiEnemyBody = entity?.component(ofType: PhysicsComponent.self) else {
        fatalError()
    }
    guard let animation = entity?.component(ofType: MovementComponent.self) else {
        fatalError()
    }
    print(aiEnemyBody.physicsBody.velocity.dx) // usually 0, despite moving across map at high speed
    if node.physicsBody!.velocity.dx > 0 {
        animation.move(direction: "left")
    } else if node.physicsBody!.velocity.dx < 0 {
        animation.move(direction: "right")
    } else {
        animation.faceForward()
    }
}

In debugging I found that the agent's change in x velocity doesn't always change when the entity is moving left or right necessarily? Is this correct behavior? I'm hoping there is another method to detect movement in a certain direction

For more context, the game is a 2d platform-style game picture


Solution

  • In case this helps anyone, I was wrongly using the physics body for the movement reference. The correct way is to use the GKAgent2D's velocity instead

        func agentWillUpdate(_ agent: GKAgent) {
            if let agent = agent as? GKAgent2D,
            let animation = entity?.component(ofType: MovementComponent.self) {
            agent.position = SIMD2<Float>(Float((node.position.x)), Float((node.position.y)))
            if agent.velocity.x < 0 {
                animation.move(direction: "left")
            } else if agent.velocity.x > 0 {
                animation.move(direction: "right")
            } else {
                animation.faceForward()
            }
        }
    }