Frage

I am creating a game in Unity3d using the GREE c# API. I am trying to get run an Action for every (username, score) in a leader board.

The code is the following:

public static void LoadBestScoreFromFriends(Action<FriendAndScore> onComplete)
{
    Gree.Leaderboard.LoadScores(LEADERBOARD_ID,
        UnityEngine.SocialPlatforms.UserScope.FriendsOnly,
        UnityEngine.SocialPlatforms.TimeScope.AllTime,
        1,
        100,
        (IScore[] scores) => {

        foreach (IScore iscore in scores)
        {
            // Since the username is needed, a second
            // call to the API must be done
            Gree.User.LoadUser(iscore.userID, 
            (Gree.User guser) => {
                FriendAndScore friend = new FriendAndScore();
                friend.Name = guser.nickname;
                friend.Score = "" + iscore.value;

                // Run the action for every (nickname, score value)
                onComplete(friend);
            }, (string error) => {
                Debug.Log("Couldn't fetch friend! error: " + error);
            });
        }
    });
}

The problem here is that the iscore.value it's always the same. It's the last element of the foreach. This make sense because the LoadUser() finishes after the foreach ends its loop.

I thought of creating a second method to do the call there. Something like:

private void GetTheUserAndCallTheAction(Action<FriendAndScore> onComplete, string userID, string score)
{
    Gree.User.LoadUser(userID, 
            (Gree.User guser) => {
                FriendAndScore friend = new FriendAndScore();
                friend.Name = guser.nickname;
                friend.Score = score;
                onComplete(friend);
            }, (string error) => {
                Debug.Log("Couldn't fetch friend! error: " + error);
            });
}

Since I am a C# newbie I wanted to know if there is a better way of handling this.

War es hilfreich?

Lösung

By design - this is how capture works when constructing lambda expression in foreach loop and executing this lambda later.

Fix - declare local copy of IScore iscore:

foreach (IScore eachScore in scores)
{
   IScore iscore = eachScore;

And Closing over the loop variable... by Eric Lippert details the behavior and related issues.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top