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..