- Home /
Prime31 Gamecenter Crash when triggering method
Hi
I'm still pretty green when it comes to c# and events. Yes I've watched the videos and read the docs, but nothing is sinking in quite yet. I'm more of a 'visual', learn by example kind of person I guess.
I'm struggling to sort out the following problem: 1. When the parameters of an achievement that is already unlocked are met again in game, to not show the achievement completion banner and not register the achievement to Gamecenter again.
What I've done so far :
public static List achievements; void Awake () { GameCenterBinding.isGameCenterAvailable(); }
void Start()
{
if (GameCenterBinding.isGameCenterAvailable() )
{
GameCenterBinding.authenticateLocalPlayer(); //Must Have
GameCenterBinding.showCompletionBannerForAchievements(); //Display banners on Achievement Unlocks...
GameCenterBinding.loadReceivedChallenges();
// GameCenterBinding.getAchievements();
}
//Listener
GameCenterManager.achievementsLoaded += achievementStatus;
}
void OnEnable()
{
//Listener for the achievements Loaded event
GameCenterManager.achievementsLoaded += achievementStatus;
}
void OnDisable()
{
GameCenterManager.achievementsLoaded -= achievementStatus;
}
void achievementStatus( List<GameCenterAchievement> achievements )
{
foreach( var achievement in achievements )
{
Debug.Log (achievement);
}
}
//Update the GC with a new unlocked achievement
public static void ReportAchievement(string id)
{
foreach (GameCenterAchievement s in achievements)
{
if (s.identifier == id)
{
Debug.Log ("Achievement already completed");
}
else
{
Debug.Log("Unlocked Achievement: "+id);
GameCenterBinding.reportAchievement( id, 100 );
}
}
}
}
So when achievement parameters are met in-game I call "GameCenterGameManager.ReportAchievement("ach_01"); However, doing so crashes the game....
Obviously, I'm doing something very wrong and am hoping someone might be able to shed some light on this for me.
What I'm trying to do is when I report a potentially accomplished achievement, I check (through identifier matching my id) that the achievement isn't already logged as completed (from achievementsLoaded event)
Any feedback or advice on this is appreciated. And be kind! I am but an artist/designer. Thanks!
Wow sorry for my terrible formatting of this question!
Not sure what happened there!
Answer by OceanBlue · May 15, 2013 at 12:23 PM
So after a lot of digging around and two days of solid learning and research, I have the answer.
I'm posting the code here so that anyone else who has a problem of not being able to turn off the Achievement Unlocked banner after it's been unlocked, here's the solution that worked for me. Hope that it saves you time!
In-game, when an achievement's parameters are met, I fire off the following:
GameCentreGameManager.ReportAchievement("MIFOS_AC1_0"); //ID on iTunesConnect
I then have a script called "GameCentreGameManager.cs" that handles the event listener and methods...... (note that I'm not including all other code that's irrelevant)
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Prime31;
public class GameCentreGameManager : MonoBehaviour {
#if UNITY_IPHONE
public static string playerName;
public static long playerHighScoreGC;
public long _score;
public static bool idFound;
public static List<GameCenterAchievement> _achievements;
// Initialise Game Centre
void Awake ()
{
GameCenterBinding.isGameCenterAvailable();
}
void Start()
{
if (GameCenterBinding.isGameCenterAvailable() )
{
GameCenterBinding.authenticateLocalPlayer(); //Must Have
GameCenterBinding.showCompletionBannerForAchievements(); //Display banners on Achievement Unlocks...
}
//Listener
GameCenterManager.achievementsLoaded += achievementStatus =>
{
_achievements = achievementStatus;
};
}
// Update the GC Leaderboard with new achievement.
// The leaderboard will determine if the score is higher than what's already been previously posted and will only post a new high score automatically, thereby stopping the achievement banner from reappearing if subsequent repeats of achievement parameters are fulfilled.
public static void ReportAchievement(string id)
{
if (_achievements !=null)
{
foreach (GameCenterAchievement i in _achievements)
{
idFound = false;
//search for achievement id in the list
if (!idFound)
{
if ( i.identifier == id)
{
Debug.Log ("Achievement already unlocked "+i.identifier);
idFound = true;
break;
}
}
}
}
if (_achievements == null || !idFound) //First achievemeent ever to be unlocked or achievement id not in the list of unlocked achievements
{
Debug.Log("Unlocked Achievement: "+id);
GameCenterBinding.reportAchievement( id, 100 );
}
}
#endif
}
I've done some rigorous testing of the above, including if whilst the game is open, and the player logs out of GameCentre via the GameCentre app, my game will automatically prompt for a user to sign in. When they do, the code above continues to function correctly for the new player, with relevant achievements unlocked etc and banner behaviour working correctly.
Also note, that for reference, I do have a Listener script that has the following.
//Update the achievements when an achievement is successfully logged to GameCentre...
void reportAchievementFinished( string identifier )
{
Debug.Log( "reportAchievementFinished: " + identifier );
//Update the list on completion of the successful achievement....
GameCenterBinding.getAchievements();
}
// When the player logs out and a new one logs in...
void playerDataLoaded( List<GameCenterPlayer> players )
{
Debug.Log( "playerDataLoaded" );
GameCenterBinding.getAchievements();
}
As mentioned above, I've been testing it for an hour now with different and new Sandbox Users and haven't had any hiccups. Of course, my experience in C# and events is very limited, so if you see an issue with what I've done above, please let me know.
Thanks to those who helped out.
Cheers
Looks awesome... just what I need, thanks for sharing!
How do you listen for reportAchievementFinished and playerDataLoaded? Do you drop the GameCentreGame$$anonymous$$anager script in all your scenes or just have one at launch with dontDestroyOnLoad? Dunno if either would make a difference.
I just have a dont destroy script on my gamemanager script.
Your answer
Follow this Question
Related Questions
Events In Javascript - Prime31 0 Answers
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers
Orientation problems with iPad and GameCenter dialog 1 Answer
Question about unsubscribing eventhandlers OnDisable and OnEnable 2 Answers