I have integrated the SKD of UnityAds into my game to show full screen interstitial video ads.
When the video is finished, a link to the AppStore is provided by the ad framework. When I select this link, the AppStore is opened. My app crashes in this moment, throwing EXC_BAD_ACCESS in CCGraphicsBufferGLUnsynchronized.
When starting my app, the UnityAds SDK is initialized like this:
[[UnityAds sharedInstance] startWithGameId:UNITYADS_MYAPP_ID
andViewController:[CCDirector sharedDirector]
];
As you can see, I am passing [CCDirector sharedDirector] as the view controller. I am mentioning this, as this might by a part of the problem?
Later I am calling the UnityAds SDK from within a Cocos2D scene like this:
-(void)showFullscreenAd {
// Stop Cocos2D rendering
[[CCDirector sharedDirector] pause];
[[CCDirector sharedDirector] stopAnimation];
// Is an ad available?
if ([[UnityAds sharedInstance] canShowAds]) {
// Display the ad
[[UnityAds sharedInstance] setZone:@"rewardedVideoZone"];
[[UnityAds sharedInstance] show];
}
}
As you can see I am stopping Cocos2D rendering before displaying the add.
When I select the AppStore link in the add, my app crashes. This is the code Xcode points me to after the crash (in class CCGraphicsBufferGLUnsynchronized)
-(void)prepare
{
_count = 0;
GLenum target = (GLenum)_type;
glBindBuffer(_type, _buffer);
==> _ptr = _mapBufferRange(target, 0, (GLsizei)(_capacity*_elementSize), BUFFER_ACCESS_WRITE);
glBindBuffer(target, 0);
CC_CHECK_GL_ERROR_DEBUG();
}
Can someone point me into the right direction for debugging?
I am running my app on an iPad and iPhone under iOS 8.1.3
OK, I found a solution myself. Seems like the crash occurs because the app is in the background and rendering continues. So all I had to do was to make sure that rendering is not resumed after the app was moved to the background.
I do it like this now:
// Added a flag to control resuming of rendering
@property (readwrite) bool resumeRendering;
[...]
-(void)showFullscreenAd {
// Stop Cocos2D rendering
[[CCDirector sharedDirector] pause];
[[CCDirector sharedDirector] stopAnimation];
// Set to resume redering by default
_resumeRendering = YES;
// Is an ad available?
if ([[UnityAds sharedInstance] canShowAds]) {
// Display the ad
[[UnityAds sharedInstance] setZone:@"rewardedVideoZone"];
[[UnityAds sharedInstance] show];
}
}
[...]
#pragma mark - UnityAdsDelegate
// This method is called when the interstitial ad is discarded
// check if rendering should be resumed
-(void)unityAdsDidHide {
if ( _resumeRendering ) {
[[CCDirector sharedDirector] resume];
[[CCDirector sharedDirector] startAnimation];
}
// do anything else here
// In my case I transfer to the next scene
[...]
}
-(void)unityAdsWillLeaveApplication {
// Will leave application. Make sure rendering is not resumed anymore
_resumeRendering = NO;
}
When the user clicks the AppStore link in the ad now, the method unityAdsWillLeaveApplication will be called and I can mark resumeRendering as false.
Hope this helps other with the same problem.