1

I'm trying to achieve VoiceChat among two connected players using GKMatch object. My players are authenticated and I'm also able to create a match using GKMatchmakerViewController.

The issue is when I receive a GKMatch object via delegate callback matchmakerViewController:didFindMatch:, I setup AudioSession and a VoiceChat object. But soon after this method is returned I get callback in GKMatch's delegate match:player:didChangeState:

Here's how I'm creating AudioSession and VoiceChat in didFindMatch callback:

- (void)matchmakerViewController:(GKMatchmakerViewController *)viewController didFindMatch:(GKMatch *)match {

    [viewController dismissViewControllerAnimated:YES completion:nil];

    self.match = match;
    match.delegate = self;

    if (!_matchStarted && match.expectedPlayerCount == 0)
    {
        NSError *err = nil;
        AVAudioSession *audioSession = [AVAudioSession sharedInstance];
        [audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:&err];
        [audioSession setActive: YES error:&err];

        if (err)
        {
            NSLog(@"%@",err.localizedDescription);
        }
        self.teamChannel = [[match voiceChatWithName:@"redTeam"] retain];

        _teamChannel.volume = 1.0f;
        _teamChannel.active = YES;

        [_teamChannel start];

        _teamChannel.playerStateUpdateHandler = ^(NSString *playerID, GKVoiceChatPlayerState state) {
            switch (state)
            {
                case GKVoiceChatPlayerSpeaking:
                    NSLog(@"Speaking...");
                    break;
                case GKVoiceChatPlayerSilent:
                    break;
                    case GKVoiceChatPlayerConnected:
                    NSLog(@"Connected.");
                    break;
                    case GKVoiceChatPlayerConnecting:
                    NSLog(@"Connecting..");
                    break;
                    case GKVoiceChatPlayerDisconnected:
                    NSLog(@"Disconnected.");
                    break;
            }
        };
    }
}

I never get a call in playerStateUpdateHandler. I get disconnected call in the following function: `- (void)match:(GKMatch *)match player:(NSString *)playerID didChangeState:(GKPlayerConnectionState)state { if (_match != match) return;

switch (state) {
    case GKPlayerStateConnected:
        NSLog(@"Player connected!");
        break;
    case GKPlayerStateDisconnected:
        NSLog(@"Player disconnected!");
        _matchStarted = NO;
        break;
    case GKPlayerStateUnknown:
        NSLog(@"Player stage Unknown.");
        break;
}

}`

Question:-

I'm unable to hear any audio on any end, am I missing something ? I've been trying this for 3 days now, and (as a side question) I'm not sure what to do with my second player. As, when there's a match I get didFindMatch on one of the device's and there's no call-back on the other device. Do I need to send a message on the other device ? about the match ?

A quick help would be very much appreciated.

Sabir Ali
  • 475
  • 2
  • 16

1 Answers1

0

It sounds like you are inviting a player rather than auto matching one, if this is the case didFindMatch is only called on the hosting device. The client finds out about this in the inviteHandler

[GKMatchmaker sharedMatchmaker].inviteHandler = ^(GKInvite *acceptedInvite, NSArray *playersToInvite) 
{
    if (acceptedInvite)
    {
        GKMatchmakerViewController *mmvc = [[GKMatchmakerViewController alloc] initWithInvite:acceptedInvite];
        mmvc.matchmakerDelegate = self;

        // Do client connection stuff here
    }
    else if (playersToInvite)
    {
        GKMatchRequest *request = [[GKMatchRequest alloc] init];
        request.minPlayers = 2;
        request.maxPlayers = 2;
        request.playersToInvite = playersToInvite;

        GKMatchmakerViewController *mmvc = [[GKMatchmakerViewController alloc] initWithMatchRequest:request];
        mmvc.matchmakerDelegate = self;

        [pViewController presentViewController:mmvc animated:YES completion:nil];
    }
};

If you are auto matching your game both players will receive a callback inside [[GKMatchmaker sharedMatchmaker] findMatchForRequest:request withCompletionHandler:^(GKMatch *match, NSError *error)

 [[GKMatchmaker sharedMatchmaker] findMatchForRequest:request withCompletionHandler:^(GKMatch *match, NSError *error) 
{
    if (error != nil)
    {
        NSLog(@"MULTIPLAYER MATCH REQUEST FAILED: %@", error.localizedDescription);
    }
    else if (match != nil)
    {
        self.m_pMatchObject = [match retain];
    }
}];
ryan.tait
  • 79
  • 1