1

I have currently a large SpriteKit game in development that uses many different characters and enemies in the game - all of which runs quite nicely as planned.

As the levels and gameplay has become more involved however, I am looking to utilize Apples GameplayKit functionality to improve the logic and ease of the games "thinking" and how efficient it runs.

The problem I am facing however, is I cannot seem to get my agentWillUpdate:(GKAgent *)agent or agentDidUpdate:(GKAgent *)agent delegate methods to run at all. I have no issue with the movement controls of my character nor do I have issue with how the GKAgent will be controlling the movement of the enemies, but I can not get these methods to fire.

Here is my header file OLevel.h:

#import "OEnemy.h"
@import SpriteKit;
@import GameplayKit;

@interface OLevel : SKScene <SKPhysicsContactDelegate>

// A component system to manage per-frame updates for all agents
@property (nonatomic, readwrite) GKComponentSystem *agentSystem;
@property (nonatomic, readwrite) OEnemy *testEnemy;
@property (nonatomic, readwrite) GKAgent2D *characterAgent;
@property (nonatomic, readwrite) GKAgent2D *enemyAgent;
@property (nonatomic, readwrite) GKGoal *seekGoal;

Here is how I have set up my SKScene OLevel.m:

- (void)initSceneWithLevel:(NSInteger)level andChapter:(NSInteger)chapter {

    currentLevel = level;
    currentChapter = chapter;

    [self setUpScene];
    [self setUpCharacter];
    [self setUpEnemyWithLocation:[enemyArray firstObject]];

}
- (void)didMoveToView:(SKView *)view {

    // Set up the agent system
    self.agentSystem = [[GKComponentSystem alloc] initWithComponentClass:[GKAgent2D class]];

    self.characterAgent = [[GKAgent2D alloc] init];
    self.characterAgent.position = (vector_float2){character.position.x, character.position.y};

    [self.agentSystem addComponent:self.testEnemy.agent];
    self.seekGoal = [GKGoal goalToSeekAgent:self.characterAgent];

    [self.testEnemy.agent.behavior setWeight:1 forGoal:self.seekGoal];


    /* >>> More of scene setup below - not relevant to GameplayKit issues <<< */
}

NOTE When I am adding my enemy to the scene, I am assigning the self.testEnemy to the enemy I create:

- (void)setUpEnemyWithLocation:(NSString *)location {
    OEnemy *enemy = [OEnemy node];
    [enemy createEnemyWithLocation:location];
    [chapterScene addChild:enemy];

    // Add enemy to enemyArray
    [enemyArray addObject:enemy];

    self.testEnemy = enemy;
    self.testEnemy.agent = [[GKAgent2D alloc] init];
    self.testEnemy.agent.behavior = [[GKBehavior alloc] init];

}

Here is my SKNode subclass OEnemy.h:

@import SpriteKit;
@import GameplayKit;

@interface OEnemy : SKNode <GKAgentDelegate>


@property (readwrite) GKAgent2D *agent;

Here is my SKNode OEnemy.m:

#import "OEnemy.h"
#import "SSOC.h"

@interface OEnemy () {

    SKSpriteNode *enemy;    
}

@end

@implementation OEnemy

- (id)init {
    if (self = [super init]) {
        // Initialization done here
        NSLog(@"Enemy is in the scene");

        // An agent to manage the movement of this node in a scene.
        _agent = [[GKAgent2D alloc] init];
        _agent.radius = 40;
        _agent.position = (vector_float2){self.position.x, self.position.y};
        _agent.delegate = self;
        _agent.maxSpeed = 100;
        _agent.maxAcceleration = 50;

    }
    return self;
}

/* Methods that are independent of GameplayKit 
.
.
.
 */

#pragma mark - GameplayKit Delegate
- (void)agentWillUpdate:(nonnull GKAgent *)agent {
    NSLog(@"will update");
}

- (void)agentDidUpdate:(nonnull GKAgent2D *)agent {
    self.position = CGPointMake(agent.position.x, agent.position.y);
    NSLog(@"did update");

}

I am at a loss as to what I have to do differently to get my simple objective met:

• I need my OLevel and it's GKComponentSystem *agentSystem to simply initialize, add the enemyAgent as a component, assign it a behavior as to what it should do, then update the node's movement attached to that agent.

If anyone can help me understand what I am doing wrong / missing, I would most appreciate it. Thank you in advance.

FYI I have followed Apple's AgentsCatalog iOS (Objective C) sample project with how they use GameplayKit for seeking, wandering, flocking, etc., but I have been unable to reproduce their functionality within my sprite project..

Will Von Ullrich
  • 2,129
  • 2
  • 15
  • 42
  • 1
    You never assign the delegate from what i see. Should have something like `self.characterAgent.delegate = self`, variable may be wrong but you should get the idea – Knight0fDragon Jul 25 '16 at 15:45
  • I reworked this whole process and now I am getting it to work nicely - thank you. All that's left now is to figure out the obstacles issue from my other post and I should be in the clear. – Will Von Ullrich Jul 25 '16 at 15:48

0 Answers0