Giter Club home page Giter Club logo

play-games-plugin-for-unity's Introduction

Google Play Games plugin for Unity

Copyright (c) 2014 Google Inc. All rights reserved.

The Google Play Games plugin for Unity® is an open-source project whose goal is to provide a plugin that allows game developers to integrate with the Google Play Games API from a game written in Unity®. However, this project is not in any way endorsed or supervised by Unity Technologies.

Unity® is a trademark of Unity Technologies.

iOS is a trademark of Apple, Inc.

Overview

The Google Play Games plugin for Unity allows you to access the Google Play Games API through Unity's social interface. The plugin provides support for the following features of the Google Play Games API:

  • sign in
  • friends
  • unlock/reveal/increment achievement
  • post score to leaderboard
  • cloud save read/write
  • show built-in achievement/leaderboards UI
  • events
  • nearby connections

NOTICE: This version of the plugin no longer supports iOS. Google Play games services for iOS is deprecated, and is not likely to function as expected. Do not use Google Play games services for iOS in new apps. See the deprecation announcement blog post for more details.

Features:

  • easy GUI-oriented project setup (integrated into the Unity GUI)
  • no need to override/customize the player Activity
  • no need to override/customize AndroidManifest.xml

System requirements:

  • Unity® 2017.4 or above.

  • To deploy on Android:

    • Android SDK
    • Android v4.0 or higher
    • Google Play Services library, version 11.6 or above

Upgrading

If you have already integrated your project with a previous version of the plugin and wish to upgrade to a new version, please refer to the upgrade instructions.

Configure Your Game

To use the plugin, you must first configure your game in the Google Play Developer Console. Follow the instructions on creating a client ID. Be particularly careful when entering your package name and your certificate fingerprints, since mistakes on those screens can be difficult to recover from.

Copy the game resources from the console

Once you configure at least one resource (event, achievement, or leaderboard), copy the resource configuration from the Google Play Developer Console, and paste it into the setup configuration in Unity. To get the resources go to the Achievements tab, then click on "Get resources" on the bottom of the list.

click Get Resources

Then click the "Android section".

Android Resources

Select all the contents of the resources window, and copy them to the clipboard.

Paste the game resources into the plugin setup dialog

Back in Unity, open the setup dialog Window > Google Play Games > Setup... > Android Setup

Android Setup

  • Enter the directory to save constants - Enter the folder for the constants file.
  • Constants class name - this is the name of the C# class to create, including namespace.
  • Resources Definition - paste the resource data from the Play Games console here.
  • Web client ID - this is the client ID of the linked web app. It is only needed if you have a web-based backend for your game and need a server auth code to be exchanged for an access token by the backend server, or if you need an id token for the player to make other, non-game, API calls.

The setup process will configure your game with the client id and generate a C# class that contains constants for each of your resources.

Setup Checklist

Make sure to do the following if they are relevant to your game:

  1. Add tester email addresses to the testing section of your game on the Play Games Console.
  2. The SHA1 fingerprint used to create the linked Android app is from the keystore used to sign the Unity application.

Add Achievements and Leaderboards

Add achievements and leaderboards to your game in the Google Play Developer Console. For each achievement and leaderboard you configure, make sure to note the corresponding achievement ID or leaderboard ID, as those will be needed when making the API calls. Achievement and leaderboard IDs are alphanumeric strings (e.g. "Cgkx9eiuwi8_AQ").

Add Events

Events allow you to track user actions in your game and report on them with Analytics. Read more about how to configure and use Events on Game Concepts - Events

Load Your Game Project

Next, load your game project into the Unity editor.

If you do not have a game project to work with, you can use the Minimal sample available in the samples directory. Using that sample will allow you to quickly test your setup and make sure you can access the API.

If you want to test a larger sample after you are familiar with the plugin, try the CubicPilot game. More information about building the samples can be found in the samples README file.

Plugin Installation

To download the plugin, clone this Git repository into your file system (or download it as a ZIP file and unpack it). Then, look for the unitypackage file in the current-build directory:

current-build/GooglePlayGamesPluginForUnity-X.YY.ZZ.unitypackage

To install the plugin, simply open your game project in Unity and import that file into your project's assets, as you would any other Unity package. This is accomplished through the Assets > Import Package > Custom Package menu item (you can also reach this menu it by right-clicking the Assets folder).

Next, make sure your current build platform is set to Android. From File > Build Settings… select Android and click Switch Platform. You should now see a new menu item was added under Window > Google Play Games. If you don't see the new menu items, refresh the assets by clicking Assets > Refresh and try again.

Android Setup

Next, set up the path to your Android SDK installation in Unity. This is located in the preferences menu, under the External Tools section.

To configure your Unity game to run with Google Play Games on Android, first open the Android SDK manager and verify that you have downloaded the following packages. Depending on if you are using the SDK manager from Android Studio, or using the standalone SDK manager, the name of the components may be different.

  • Google Play Services
  • Android Support Library
  • Local Maven repository for Support Libraries (Also known as Android Support Repository)
  • Google Repository
  • Android 6.0 (API 23) (this does not affect the min SDK version).

Next, configure your game's package name. To do this, click File > Build Settings, select the Android platform and click Player Settings to show Unity's Player Settings window. In that window, look for the Bundle Identifier setting under Other Settings. Enter your package name there (for example com.example.my.awesome.game).

In order to sign in to Play Game Services, you need to sign your APK file, make sure that you are signing it with the correct certificate, that is, the one that corresponds to the SHA1 certificate fingerprint you entered in the Developer Console during the setup.

Next, click the Window |Google Play Games|Setup - Android setup menu item. This will display the Android setup screen.

Enter the Constants class name. This is the name of the fully qualified class that will be updated (or created) which contains the IDs of the game resources. The format of the name is .. For example, AwesomeGame.GPGSIds

Paste the resource definition data. This is the XML data from the Google Play Developer Console which contains the resource IDs as well as the Application ID for Android.

This data is found in the Google Play Developer Console by clicking "Get resources" on any of the resource pages (e.g. Achievements or Leaderboards), then clicking Android.

After pasting the data into the text area, click the Setup button.

Note: If you are using a web application or backend server with your game, you can link the web application to the game to enable getting the player's id token and/or email address. To do this, link a web application to the game in the Google Play Developer Console, and enter the client id for the web application into the setup dialog.

Additional instructions on building for Android on Windows

If you are using Windows, you must make sure that your Java SDK installation can be accessed by Unity. To do this:

  1. Set the JAVA_HOME environment variable to your Java SDK installation path (for example, C:\Program Files\Java\jdk1.7.0_45).
  2. Add the Java SDK's bin folder to your PATH environment variable (for example, C:\Program Files\Java\jdk1.7.0_45\bin)
  3. Reboot.

How to edit environment variables: In Windows 2000/XP/Vista/7, right-click My Computer, then Properties, then go to Advanced System Properties (or System Properties and then click the Advanced tab), then click Environment Variables. On Windows 8, press Windows Key + W and search for environment variables For more information, consult the documentation for your version of Windows.

Run the Project

If you are working with the Smoketest sample, you should be able to build and run the project at this point. You will see the automatic sign-in attempt, when Smoketest starts.

To build and run on Android, click File > Build Settings, select the Android platform, then Switch to Platform, then Build and Run.

ISocialPlatform Compliance

The Google Play Games plugin implements Unity's social interface, for compatibility with games that already use that interface when integrating with other platforms. However, some features are unique to Play Games and are offered as extensions to the standard social interface provided by Unity.

The standard API calls can be accessed through the Social.Active object, which is a reference to an ISocialPlatform interface. The non-standard Google Play Games extensions can be accessed by casting the Social.Active object to the PlayGamesPlatform class, where the additional methods are available.

Nearby Connections Configuration

In order to use nearby connections, a service id which uniquely identifies the set of applications that can interact needs to be configured. This is done by clicking the Window > Google Play Games > Nearby Connections setup... menu item. This will display the nearby connections setup screen. On this screen enter the service ID you want to use. It should be something that identifies your application, and follows the same rules as the bundle id (for example: com.example.myawesomegame.nearby). Once you enter the id, press Setup.

To use nearby connections, the player does not need to be authenticated, and no Google Play Developer Console configuration is needed.

For detailed information on nearby connection usage, please refer to nearby connections.

Sign in

A connection to Game services will be automatically formed when your game is opened. Once the connection is successful the player will be welcomed with a pop-up and your game is ready to begin using the Games Unity Plugin.

Note: If a user has never used Google Play Games on this device, they will be automatically taken through one-time setup operations such as creating a profile with the Play Games app.

In the Start method of your script, listen to the result of the automatic sign-in attempt, fetch the authentication status and disable Play Games Services features if the user is not signed in.

    using GooglePlayGames;

    public void Start() {
      PlayGamesPlatform.Instance.Authenticate(ProcessAuthentication);
    }

    internal void ProcessAuthentication(SignInStatus status) {
      if (status == SignInStatus.Success) {
        // Continue with Play Games Services
      } else {
        // Disable your integration with Play Games Services or show a login button
        // to ask users to sign-in. Clicking it should call
        // PlayGamesPlatform.Instance.ManuallyAuthenticate(ProcessAuthentication).
      }
    }
}

The result code is an enum, which gives you different failure reasons that will help you understand sign-in failures better.

If you prefer using Unity’s Social platform, then you can alternatively use the code block below.

  using GooglePlayGames;

  public void Start() {
    PlayGamesPlatform.Activate();
    Social.localUser.Authenticate(ProcessAuthentication);
  }

Note that you cannot make any games API calls (unlock achievements, post scores, etc) until you get a successful return value from Authenticate, so it is good practice to put up a standby screen until the callback is called, to make sure the user can't start playing the game until the authentication process completes.

Friends

Play Games Friends allows players to create and maintain a cross-games friends list. You can request access to this friends list to help your players play your game with their friends. See the Friends concept page for more details on the friends system.

To enable Friends, use the following functions:

  • View friends: Request access to a player’s friends list, so you can add their play games friends to your in-game friends list
  • View a player profile: Let a player view the Play Games profile of another player. This is essential so a player knows who their friends are, and can connect to other Play Games players in your game. This will need to be tied to a UI element to trigger the popup. See the friends guidelines for details.

See the best practices guidelines for instructions on how best to implement these APIs.

Note: To use Friends, you need to update your PGS SDK to version 20.0.0

View friends

There are two ways to load friends, either using the ISocial framework or directly with PlayGamesPlatform.

Loading friends with the ISocial framework

Social.localUser.LoadFriends((success) =>  {
    Debug.Log("Friends loaded OK: " + ok));
    foreach(IUserProfile p in Social.localUser.friends) {
         Debug.Log(p.userName + " is a friend");
    }

However, this call will fail if the current player has not yet granted permission to the game to access this information. Use GetLastLoadFriendsStatus to check if LoadFriends failed due to missing consent.

 PlayGamesPlatform.Instance.GetLastLoadFriendsStatus((status) => {
    // Check for consent
    if (status == LoadFriendsStatus.ResolutionRequired) {
        // Ask for resolution.
    }
});

A game can ask the current player to share the friends list by calling AskForLoadFriendsResolution.

PlayGamesPlatform.Instance.AskForLoadFriendsResolution((result) => {
    if (result == UIStatus.Valid) {
        // User agreed to share friends with the game. Reload friends.
    } else {
        // User doesn’t agree to share the friends list.
    }
});

This function will show the appropriate platform-specific friends sharing UI. This UI asks the player if they want to share their friends with the game.

Loading friends with PlayGamesPlatform

Another way of loading friends is to use LoadFriends and LoadMoreFriends:

PlayGamesPlatform.Instance.LoadFriends(pageSize, forceReload, (status) => {
    // Check if the call is successful and if there are more friends to load.
});

PlayGamesPlatform.Instance.LoadMoreFriends(pageSize, (status) => {
    // Check if there are more friends to load.
});

The pageSize param represents the number of entries to request for this page. Note that if cached data already exists, the returned buffer may contain more than this size. The buffer is guaranteed to contain at least this many entries if the collection contains enough records. If forceReload is set to true, this call will clear any locally-cached data and attempt to fetch the latest data from the server. This would commonly be used for actions like a user-initiated refresh. Normally, this should be set to false to gain the advantages of data caching.

If the callback returns LoadFriendsStatus.LoadMore, then there are more friends to load. LoadFriendsStatus.ResolutionRequired signals that the user has not shared the friends list and you can directly call PlayGamesPlatform.Instance.AskForLoadFriendsResolution.

Determining friends list visibility

Use PlayGamesPlatform.Instance.GetFriendsListVisibility to check if the user has shared the friends list with the game. Possible return statuses are:

  • FriendsListVisibilityStatus.RequestRequired indicates you must ask for consent.
  • FriendsListVisibilityStatus.Visible indicates that loading the friends list should succeed.
  • FriendsListVisibilityStatus.Unknown generally shouldn't happen. You can set forceReload to true to refresh the data.
PlayGamesPlatform.Instance.GetFriendsListVisibility(forceReload, (friendsListVisibilityStatus) => {});

View a player profile

To add or remove a player as a friend, use the show and compare profile function. This function triggers a bottom sheet dialog showing the Play Games profile of the user; call the function with the player Id of the requested player. If the player and friend have in-game nicknames, use them in the call to add more context to the profile UI:

PlayGamesPlatform.Instance.ShowCompareProfileWithAlternativeNameHintsUI(
    mFirstFriendId, /* otherPlayerInGameName= */ null, /* currentPlayerInGameName= */ null,
    (result) => {
        // Profile comparison view has closed.
});

Player Statistics

The Player Stats API let you tailor game experiences to specific segments of players and different stages of the player lifecycle. You can build tailored experiences for each player segment based on how players are progressing, spending, and engaging. For example, you can use this API to take proactive actions to encourage a less active player to re-engage with your game, such as by displaying and promoting new in-game items when the player signs in.

The callback takes two parameters:

  1. The result code less than or equal to zero is success. See CommonStatusCodes for all values.
  2. The PlayerStats object of type GooglePlayGames.PlayGamesLocalUser.PlayerStats

For more information see Player Stats.

The player stats are available after authenticating:

    ((PlayGamesLocalUser)Social.localUser).GetStats((rc, stats) =>
        {
            // -1 means cached stats, 0 is succeess
            // see  CommonStatusCodes for all values.
            if (rc <= 0 && stats.HasDaysSinceLastPlayed()) {
                Debug.Log("It has been " + stats.DaysSinceLastPlayed + " days");
            }
        });

Revealing/Unlocking an Achievement

To unlock an achievement, use the Social.ReportProgress method with a progress value of 100.0f:

    using GooglePlayGames;
    using UnityEngine.SocialPlatforms;
    ...
    // unlock achievement (achievement ID "Cfjewijawiu_QA")
    Social.ReportProgress("Cfjewijawiu_QA", 100.0f, (bool success) => {
      // handle success or failure
    });

Notice that according to the expected behavior of Social.ReportProgress, a progress of 0.0f means revealing the achievement and a progress of 100.0f means unlocking the achievement. Therefore, to reveal an achievement (that was previously hidden) without unlocking it, simply call Social.ReportProgress with a progress of 0.0f.

Incrementing an Achievement

If your achievement is incremental, the Play Games implementation of Social.ReportProgress will try to behave as closely as possible to the expected behavior according to Unity's social API, but may not be exact. For this reason, we recommend that you do not use Social.ReportProgress for incremental achievements. Instead, use the PlayGamesPlatform.IncrementAchievement method, which is a Play Games extension.

    using GooglePlayGames;
    using UnityEngine.SocialPlatforms;
    ...
    // increment achievement (achievement ID "Cfjewijawiu_QA") by 5 steps
    PlayGamesPlatform.Instance.IncrementAchievement(
        "Cfjewijawiu_QA", 5, (bool success) => {
            // handle success or failure
    });

Posting a Score to a Leaderboard

To post a score to a leaderboard, call Social.ReportScore.

    using GooglePlayGames;
    using UnityEngine.SocialPlatforms;
    ...
    // post score 12345 to leaderboard ID "Cfji293fjsie_QA")
    Social.ReportScore(12345, "Cfji293fjsie_QA", (bool success) => {
        // handle success or failure
    });

To post a score and include a metadata tag use the Play Game Services instance directly:

    using GooglePlayGames;
    using UnityEngine.SocialPlatforms;
    ...
    // post score 12345 to leaderboard ID "Cfji293fjsie_QA" and tag "FirstDaily")
    Social.ReportScore(12345, "Cfji293fjsie_QA", "FirstDaily", (bool success) => {
        // handle success or failure
    });

Note that the platform and the server will automatically discard scores that are lower than the player's existing high score, so you can submit scores freely without any checks to test whether or not the score is greater than the player's existing score.

Showing the Achievements UI

To show the built-in UI for all achievements, call Social.ShowAchievementsUI.

    using GooglePlayGames;
    using UnityEngine.SocialPlatforms;
    ...
    // show achievements UI
    Social.ShowAchievementsUI();

Showing the Leaderboard UI

To show the built-in UI for all leaderboards, call Social.ShowLeaderboardUI.

    using GooglePlayGames;
    using UnityEngine.SocialPlatforms;
    ...
    // show leaderboard UI
    Social.ShowLeaderboardUI();

If you wish to show a particular leaderboard instead of all leaderboards, you can pass a leaderboard ID to the method. This, however, is a Play Games extension, so the Social.Active object needs to be cast to a PlayGamesPlatform object first:

    using GooglePlayGames;
    using UnityEngine.SocialPlatforms;
    ...
    // show leaderboard UI
    PlayGamesPlatform.Instance.ShowLeaderboardUI("Cfji293fjsie_QA");

Accessing Leaderboard data

There are 2 methods to retrieving the leaderboard score data.

Using Social.ILeaderboard

This method uses the ILeaderboard interface to define the scope and filters for getting the data. This approach allows you to configure:

  1. The leaderboard Id
  2. The collection (social or public)
  3. The timeframe (daily, weekly, all-time)
  4. The rank position to start retrieving scores.
  5. The number of scores (the default is 25).
  6. Filter by user id.

If the from parameter is non-positive, then the results returned are player-centered, meaning the scores around the current player's score are returned.

    ILeaderboard lb = PlayGamesPlatform.Instance.CreateLeaderboard();
    lb.id = "MY_LEADERBOARD_ID";
    lb.LoadScores(ok =>
        {
            if (ok) {
                LoadUsersAndDisplay(lb);
            }
            else {
                Debug.Log("Error retrieving leaderboardi");
            }
        });

Using PlayGamesPlatform.LoadScores()

This method uses the PlayGamesPlatform directly. This approach provides additional flexibility and information when accessing the leaderboard data.

    PlayGamesPlatform.Instance.LoadScores(
            GPGSIds.leaderboard_leaders_in_smoketesting,
            LeaderboardStart.PlayerCentered,
            100,
            LeaderboardCollection.Public,
            LeaderboardTimeSpan.AllTime,
            (data) =>
            {
                mStatus = "Leaderboard data valid: " + data.Valid;
                mStatus += "\n approx:" +data.ApproximateCount + " have " + data.Scores.Length;
            });

The parameters for LoadScores() are:

  1. leaderboardId
  2. start position (top scores or player centered)
  3. row count
  4. leaderboard collection (social or public)
  5. time span (daily, weekly, all-time)
  6. callback accepting a LeaderboardScoreData object.

The LeaderboardScoreData class is used to return information back to the caller when loading scores. The members are: 1. Id - the leaderboard id 2. Valid - true if the returned data is valid (the call was successful) 3. Status - the ResponseStatus of the call 4. ApproximateCount - the approximate number of scores in the leaderboard 5. Title - the title of the leaderboard 6. PlayerScore - the score of the current player 7. Scores - the list of scores 8. PrevPageToken - a token that can be used to call LoadMoreScores() to get the previous page of scores. 9. NextPageToken - a token that can be used to call LoadMoreScores() to get the next page of scores.

    void GetNextPage(LeaderboardScoreData data)
    {
        PlayGamesPlatform.Instance.LoadMoreScores(data.NextPageToken, 10,
            (results) =>
            {
                mStatus = "Leaderboard data valid: " + data.Valid;
                mStatus += "\n approx:" +data.ApproximateCount + " have " + data.Scores.Length;
            });
    }

This call may fail when trying to load friends with ResponseCode.ResolutionRequired if the user has not shared their friends list with the game. In this case, use AskForLoadFriendsResolution to request access.

Getting player names

Each score has the userId of the player that made the score. You can use Social.LoadUsers() to load the player profile. Remember that the contents of the player profile are subject to privacy settings of the players.

    internal void LoadUsersAndDisplay(ILeaderboard lb)
    {
        // get the user ids
        List<string> userIds = new List<string>();

        foreach(IScore score in lb.scores) {
            userIds.Add(score.userID);
        }
        // load the profiles and display (or in this case, log)
        Social.LoadUsers(userIds.ToArray(), (users) =>
            {
                string status = "Leaderboard loading: " + lb.title + " count = " +
                    lb.scores.Length;
                foreach(IScore score in lb.scores) {
                    IUserProfile user = FindUser(users, score.userID);
                    status += "\n" + score.formattedValue + " by " +
                        (string)(
                            (user != null) ? user.userName : "**unk_" + score.userID + "**");
                }
                Debug.log(status);
            });
    }

Recording Events

Incrementing an event is very simple, just call the following method:

    using GooglePlayGames;
    ...
    // Increments the event with Id "YOUR_EVENT_ID" by 1
    PlayGamesPlatform.Instance.Events.IncrementEvent("YOUR_EVENT_ID", 1);

This call is "fire and forget", it will handle batching and execution for you in the background.

Saving Game State to the Cloud

For details on saved games concepts and APIs please refer to the documentation.

Displaying saved games UI

The standard UI for selecting or creating a saved game entry is displayed by calling:

    void ShowSelectUI() {
        uint maxNumToDisplay = 5;
        bool allowCreateNew = false;
        bool allowDelete = true;

        ISavedGameClient savedGameClient = PlayGamesPlatform.Instance.SavedGame;
        savedGameClient.ShowSelectSavedGameUI("Select saved game",
            maxNumToDisplay,
            allowCreateNew,
            allowDelete,
            OnSavedGameSelected);
    }


    public void OnSavedGameSelected (SelectUIStatus status, ISavedGameMetadata game) {
        if (status == SelectUIStatus.SavedGameSelected) {
            // handle selected game save
        } else {
            // handle cancel or error
        }
    }

Opening a saved game

In order to read or write data to a saved game, the saved game needs to be opened. Since the saved game state is cached locally on the device and saved to the cloud, it is possible to encounter conflicts in the state of the saved data. A conflict happens when a device attempts to save state to the cloud but the data currently on the cloud was written by a different device. These conflicts need to be resolved when opening the saved game data. There are 2 open methods that handle conflict resolution, the first OpenWithAutomaticConflictResolution accepts a standard resolution strategy type and automatically resolves the conflicts. The other method, OpenWithManualConflictResolution accepts a callback method to allow the manual resolution of the conflict.

See GooglePlayGames/BasicApi/SavedGame/ISavedGameClient.cs for more details on these methods.

    void OpenSavedGame(string filename) {
        ISavedGameClient savedGameClient = PlayGamesPlatform.Instance.SavedGame;
        savedGameClient.OpenWithAutomaticConflictResolution(filename, DataSource.ReadCacheOrNetwork,
            ConflictResolutionStrategy.UseLongestPlaytime, OnSavedGameOpened);
    }

    public void OnSavedGameOpened(SavedGameRequestStatus status, ISavedGameMetadata game) {
        if (status == SavedGameRequestStatus.Success) {
            // handle reading or writing of saved game.
        } else {
            // handle error
        }
    }

Writing a saved game

Once the saved game file is opened, it can be written to save the game state. This is done by calling CommitUpdate. There are four parameters to CommitUpdate:

  1. the saved game metadata passed to the callback passed to one of the Open calls.
  2. the updates to make to the metadata.
  3. the actual byte array of data
  4. a callback to call when the commit is complete.
    void SaveGame (ISavedGameMetadata game, byte[] savedData, TimeSpan totalPlaytime) {
        ISavedGameClient savedGameClient = PlayGamesPlatform.Instance.SavedGame;

        SavedGameMetadataUpdate.Builder builder = new SavedGameMetadataUpdate.Builder();
        builder = builder
            .WithUpdatedPlayedTime(totalPlaytime)
            .WithUpdatedDescription("Saved game at " + DateTime.Now());
        if (savedImage != null) {
            // This assumes that savedImage is an instance of Texture2D
            // and that you have already called a function equivalent to
            // getScreenshot() to set savedImage
            // NOTE: see sample definition of getScreenshot() method below
            byte[] pngData = savedImage.EncodeToPNG();
            builder = builder.WithUpdatedPngCoverImage(pngData);
        }
        SavedGameMetadataUpdate updatedMetadata = builder.Build();
        savedGameClient.CommitUpdate(game, updatedMetadata, savedData, OnSavedGameWritten);
    }

    public void OnSavedGameWritten (SavedGameRequestStatus status, ISavedGameMetadata game) {
        if (status == SavedGameRequestStatus.Success) {
            // handle reading or writing of saved game.
        } else {
            // handle error
        }
    }

    public Texture2D getScreenshot() {
        // Create a 2D texture that is 1024x700 pixels from which the PNG will be
        // extracted
        Texture2D screenShot = new Texture2D(1024, 700);

        // Takes the screenshot from top left hand corner of screen and maps to top
        // left hand corner of screenShot texture
        screenShot.ReadPixels(
            new Rect(0, 0, Screen.width, (Screen.width/1024)*700), 0, 0);
        return screenShot;
    }

Reading a saved game

Once the saved game file is opened, it can be read to load the game state. This is done by calling ReadBinaryData.

    void LoadGameData (ISavedGameMetadata game) {
        ISavedGameClient savedGameClient = PlayGamesPlatform.Instance.SavedGame;
        savedGameClient.ReadBinaryData(game, OnSavedGameDataRead);
    }

    public void OnSavedGameDataRead (SavedGameRequestStatus status, byte[] data) {
        if (status == SavedGameRequestStatus.Success) {
            // handle processing the byte array data
        } else {
            // handle error
        }
    }

Deleting a saved game

Once the saved game file is opened, it can be deleted. This is done by calling Delete.

    void DeleteGameData (string filename) {
        // Open the file to get the metadata.
        ISavedGameClient savedGameClient = PlayGamesPlatform.Instance.SavedGame;
        savedGameClient.OpenWithAutomaticConflictResolution(filename, DataSource.ReadCacheOrNetwork,
            ConflictResolutionStrategy.UseLongestPlaytime, DeleteSavedGame);
    }

    public void DeleteSavedGame(SavedGameRequestStatus status, ISavedGameMetadata game) {
        if (status == SavedGameRequestStatus.Success) {
            ISavedGameClient savedGameClient = PlayGamesPlatform.Instance.SavedGame;
            savedGameClient.Delete(game);
        } else {
            // handle error
        }
    }

Retrieving server authentication codes

In order to access Google APIs on a backend web server on behalf of the current player, you need to get an authentication code from the client application and pass this to your web server application. This code can then be exchanged for an access token to make calls to the various APIs. For more details on this flow see: Google Sign-In for Websites.

To get the server side access code:

  1. Configure the web client id of the web application linked to your game in the Play Game Console.
  2. Call PlayGamesPlatform.Instance.RequestServerSideAccess once the player is authenticated to get the server side access code.
  3. Pass this code to your server application.
  PlayGamesPlatform.Instance.RequestServerSideAccess(
    /* forceRefreshToken= */ false,
    code -> {
      // send code to server
    });

Decreasing apk size

It is possible to decrease the size of the Play Games Services Unity Plugin by removing code for the Play Games Services features that your game doesn’t use by using Proguard. Proguard will remove the Play Games Unity plugin code for features that are not used in your game, so your game ships with only the code that is needed and minimizes the size impact of using Play Games Services.

Additionally, it is possible to reduce the size of the entire Unity project using Unity’s Managed Code Stripping, which will compress your entire project. This can be used in conjunction with Proguard.

Play Games Services Proguard configuration

  1. Go to File > Build Settings > Player Settings and click Publishing Settings section. Choose Proguard for Minify > Release. Then, enable User Proguard File. If you want the plugin to be proguarded for debug apks as well, you can choose Proguard for Minify > Debug.
  2. Copy the content of the proguard configuration into Assets/Plugins/Android/proguard-user.txt.

(Advanced) Using the Plugin Without Overriding the Default Social Platform

When you call PlayGamesPlatform.Activate, Google Play Games becomes your default social platform implementation, which means that static calls to methods in Social and Social.Active will be carried out by the Google Play Games plugin. This is the desired behavior for most games using the plugin.

However, if for some reason you wish to keep the default implementation accessible (for example, to use it to submit achievements and leaderboards to a different social platform), you can use the Google Play Games plugin without overriding the default one. To do this:

  1. Do not call PlayGamesPlatform.Activate
  2. If Xyz is the name of a method you wish to call on the Social class, do not call Social.Xyz. Instead, call PlayGamesPlatform.Instance.Xyz
  3. Do not use Social.Active when interacting with Google Play Games. Instead, use PlayGamesPlatform.Instance.

That way, you can even submit scores and achievements simultaneously to two or more social platforms:

    // Submit achievement to original default social platform
    Social.ReportProgress("MyAchievementIdHere", 100.0f, callback);

    // Submit achievement to Google Play
    PlayGamesPlatform.Instance.ReportProgress("MyGooglePlayAchievementIdHere", 100.0f, callback);

Special Thanks

This section lists people who have contributed to this project by writing code, improving documentation or fixing bugs.

  • Dgizusse for figuring out that setting JAVA_HOME is necessary on Windows.
  • antonlicht for fixing a bug with the parameter type of showErrorDialog on the support library.
  • pR0Ps for fixing an issue where OnAchievementsLoaded was not accepting an OPERATION_DEFERRED result code as a success.
  • friikyeu for helping debug an issue that caused API calls to be queued up rather than executed even when connected.

play-games-plugin-for-unity's People

Contributors

andrewlevada avatar bhallionohbibi avatar cya-x avatar edwardrowe avatar hak avatar mpartel avatar ozdemir08 avatar rlzicar avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

play-games-plugin-for-unity's Issues

Action scheduled for later (connection currently in progress) [13401757]

Hi guys,

first of all Thank you for your plugins. Really appreciated!

Almost each time the game start and the user login manually, when there's a request for leaderboard or postScore, nothing happens. Every calls is put in a queue and wait until...ever. The only way I found is to put the game in background manually and come back and every actions in the queue happens. What can we do? We are testing it on Nexus 7 and Nexus S.

Thank you
David

Minimal Sample android export problem

eclipse import sample project and run

how slove?

02-28 20:50:39.191: I/Unity(14379): Exception: java.lang.ClassNotFoundException: com.google.example.games.basegameutils.GameHelper
02-28 20:50:39.191: I/Unity(14379): at UnityEngine.AndroidJNISafe.CheckException () [0x00000] in :0
02-28 20:50:39.191: I/Unity(14379): at UnityEngine.AndroidJNISafe.CallStaticObjectMethod (IntPtr clazz, IntPtr methodID, UnityEngine.jvalue[] args) [0x00000] in :0
02-28 20:50:39.191: I/Unity(14379): at UnityEngine.AndroidJavaObject._CallStatic[AndroidJavaObject](System.String methodName, System.Object[] args) [0x00000] in :0
02-28 20:50:39.191: I/Unity(14379): at UnityEngine.AndroidJavaObject.CallStatic[AndroidJavaObject](System.String methodName, System.Object[] args) [0x00000] in :0
02-28 20:50:39.191: I/Unity(14379): at UnityEngine.AndroidJavaObject.FindClass (System.String name) [0x00000] in :0
02-28 20:50:39.191: I/Unity(14379): at UnityEngine.AndroidJavaObject._AndroidJavaObject (System.String className, System.Object[] args) [0x00000] in :0
02-28 20:50:39.191: I/Unity(14379): at UnityEngine.AndroidJavaObject..ctor (System.String className, System.Object[] args) [0x00000] in :0
02-28 20:50:39.191: I/Unity(14379): at GooglePlayGames.Android.Game
02-28 20:50:39.251: I/Unity(14379): NullReferenceException: Object reference not set to an instance of an object
02-28 20:50:39.251: I/Unity(14379): at GooglePlayGames.Android.AndroidClient+c__AnonStorey0.<>m__1 () [0x00000] in :0
02-28 20:50:39.251: I/Unity(14379): at UnityEngine.AndroidJavaRunnableProxy.run () [0x00000] in :0
02-28 20:50:39.251: I/Unity(14379): at System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in :0
02-28 20:50:39.251: I/Unity(14379): Rethrow as TargetInvocationException: UnityEngine.AndroidJavaRunnableProxy.run()
02-28 20:50:39.251: I/Unity(14379): at UnityEngine.AndroidJavaProxy.Invoke (System.String methodName, System.Object[] args) [0x00000] in :0
02-28 20:50:39.251: I/Unity(14379): at UnityEngine.AndroidJavaProxy.Invoke (System.String methodName, UnityEngine.AndroidJavaObject[] javaArgs) [0x00000] in :0
02-28 20:50:39.251: I/Unity(14379): at UnityEngine._AndroidJNIHelper.InvokeJavaProxyMethod (UnityEngine.AndroidJavaProxy proxy, IntPtr jmethodName, IntPtr jargs) [0x00000] in :0
02-28 20:50:39.251: I/Unity(14379):

Connection state almost always resets

On my phone (and I assume many others), OnResume() is called after the login is successful. OnResume sets mConnectionState to ConnectionState.Connecting, and it will never go back to Connected after that. I assume this all happens because Unity calls OnApplicationPause(false) after returning from the sign in overlay activity.

Achievements, Leaderboards generally still work, but I had issues with loading cloud saves because of this.

Commenting out the line in OnResume() that changes the connection state works as a temporary fix.

I'm using the newest version of Unity3D, this plugin and the play services sdk. I can give you more details about my setup if you cannot reproduce this issue.

i don't know, this is problem. help me

  1. Sample Project down

  2. Sample Minimal open

  3. GooglePlayGamesPlugin-0.8.01 import

  4. Android Setup Open and write my app-id

  5. Unity Player Setting Open and Write My Pakage name

  6. Add Key sining

  7. build and run
    But!!
    App start and Authenticate Click

  8. Test Accout Choice

  9. Sign Error : the application is incorrectly configured. check that the package name and ~~~~~~~

  10. Eclipse Log
    No package identifier when getting value for resource number 0x00000000
    android.content.res.Resources$NotFoundException: String resource ID #0x0
    at android.content.res.Resources.getText(Resources.java:1068)
    at android.content.res.Resources.getString(Resources.java:1162)
    at com.google.example.games.basegameutils.GameHelperUtils.getAppIdFromResource(GameHelperUtils.java:138)
    at com.google.example.games.basegameutils.GameHelperUtils.printMisconfiguredDebugInfo(GameHelperUtils.java:122)
    at com.google.example.games.basegameutils.GameHelper.giveUp(GameHelper.java:788)
    at com.google.example.games.basegameutils.GameHelper.onActivityResult(GameHelper.java:533)
    at com.google.example.games.pluginsupport.HelperActivity.onActivityResult(HelperActivity.java:41)
    at android.app.Activity.dispatchActivityResult(Activity.java:5563)
    at android.app.ActivityThread.deliverResults(ActivityThread.java:3514)
    at android.app.ActivityThread.handleSendResult(ActivityThread.java:3561)
    at android.app.ActivityThread.access$1200(ActivityThread.java:168)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1377)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:137)
    at android.app.ActivityThread.main(ActivityThread.java:5493)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:525)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1209)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1025)
    at dalvik.system.NativeStart.main(Native Method)
    App ID from : ??? (failed to retrieve APP ID)

    Check that the above information matches your setup in
    Developer Console. Also, check that you're logging in with the
    right account (it should be listed in the Testers section if
    your project is not yet published).

    For more information, refer to the troubleshooting guide:
    http://developers.google.com/games/services/android/troubleshooting

What is Problem????

app-id, package name, test accout is Google developer consol Register Successed

FR: Authorization in background iOS like

Subj. It possible? Players unhappy forced authorization that occurs when entering the game. You can make an attempt to log occurred in background mode like in iOS gamecenter native authorization?

No "Welcome back" screen on Android

Originally reported in #47 (Small Bug List).

"No 'welcome back' on sign in after closing app from multitasking and reopening (where sign in is automatic) - edit to this one. I have noticed if the app is just closed but stays active in b/g then after a long delay and returning to game you do get a 'Welcome {name}' box."

iOS authentication problems...

So after much work getting this plugin to work in our unit test project, I've hit a road-block for the iOS version of this plugin... basically, when I try to authenticate this occurs in the log of XCode: (I've replaced the authentication tokens with )

Changing authenication provider from AP_FACEBOOK to AP_GOOGLE_PLAY.

(Filename: /Applications/buildAgent/work/d3d49558e4d408f4/artifacts/iPhonePlayer-armv7Generated/UnityEngineDebug.cpp Line: 53)

[Play Games Plugin DLL] Activating PlayGamesPlatform.

(Filename: /Applications/buildAgent/work/d3d49558e4d408f4/artifacts/iPhonePlayer-armv7Generated/UnityEngineDebug.cpp Line: 53)

[Play Games Plugin DLL] PlayGamesPlatform activated: GooglePlayGames.PlayGamesPlatform

(Filename: /Applications/buildAgent/work/d3d49558e4d408f4/artifacts/iPhonePlayer-armv7Generated/UnityEngineDebug.cpp Line: 53)

[Play Games Plugin DLL] Note: debug logs enabled on IOSClient.

(Filename: /Applications/buildAgent/work/d3d49558e4d408f4/artifacts/iPhonePlayer-armv7Generated/UnityEngineDebug.cpp Line: 53)

2014-03-10 17:16:30.494 KIUnityUnitTest[8156:907] Debug logs enabled!
[Play Games Plugin DLL] IOSClient.Authenticate

(Filename: /Applications/buildAgent/work/d3d49558e4d408f4/artifacts/iPhonePlayer-armv7Generated/UnityEngineDebug.cpp Line: 53)

2014-03-10 17:16:30.497 KIUnityUnitTest[8156:907] GPGSAuthenticateWithCallback.
2014-03-10 17:16:30.498 KIUnityUnitTest[8156:907] GPGSManager initializing and authenticating.
2014-03-10 17:16:30.500 KIUnityUnitTest[8156:907] GPPSignIn initialized.
2014-03-10 17:16:30.501 KIUnityUnitTest[8156:907] GPPSignIn attempting sign in now.
2014-03-10 17:16:31.975 KIUnityUnitTest[8156:907] GPGSManager Finished with auth.
2014-03-10 17:16:31.979 KIUnityUnitTest[8156:907] Success signing in to Google! Auth object is GTMOAuth2Authentication 0x8ead180: {accessToken="", refreshToken="", expirationDate="2014-03-10 23:16:31 +0000"}
2014-03-10 17:16:31.980 KIUnityUnitTest[8156:907] GPGSManager Starting Google Games sign in.
2014-03-10 17:16:31.988 KIUnityUnitTest[8156/0x3dfc6b88] [lvl=3] -[GPGManager updateRpcEndpoints] Games URL [https://www.googleapis.com/rpc?prettyprint=false] Version [v1]

2014-03-10 17:16:32.322 KIUnityUnitTest[8156/0x3dfc6b88] [lvl=3] -[GPGManager applicationId] Application ID expected to be a valid, non-empty string.
2014-03-10 17:16:32.322 KIUnityUnitTest[8156/0x3dfc6b88] [lvl=3] -[GPGManager modelForApplicationId:] Expecting valid application id.
2014-03-10 17:16:32.515 KIUnityUnitTest[8156/0x3dfc6b88] [lvl=3] -[GPGManager updateRpcEndpoints] Games URL [https://www.googleapis.com/rpc?prettyprint=false] Version [v1]

2014-03-10 17:16:32.520 KIUnityUnitTest[8156/0x3dfc6b88] [lvl=3] -[GPGManager applicationId] Application ID expected to be a valid, non-empty string.
2014-03-10 17:16:32.521 KIUnityUnitTest[8156/0x3dfc6b88] [lvl=3] -[GPGManager modelForApplicationId:] Expecting valid application id.

Android is working fine, and Facebook is working fine on IOS... just can't get google play to authenticate correctly.

Cannot implicitly convert type `GooglePlayGames.BasicApi.Achievement' to `Achievement'

After import asset I see this in Console:

Assets/GooglePlayGames/ISocialPlatform/PlayGamesPlatform.cs(271,25): error CS0029: Cannot implicitly convert type 'GooglePlayGames.BasicApi.Achievement' to 'Achievement'

Assets/GooglePlayGames/ISocialPlatform/PlayGamesPlatform.cs(277,37): error CS1061: Type 'Achievement' does not contain a definition for 'IsIncremental' and no extension method 'IsIncremental' of type 'Achievement' could be found (are you missing a using directive or an assembly reference?)

Assets/GooglePlayGames/ISocialPlatform/PlayGamesPlatform.cs(278,32): error CS1061: Type 'Achievement' does not contain a definition for 'CurrentSteps' and no extension method 'CurrentSteps' of type 'Achievement' could be found (are you missing a using directive or an assembly reference?)

Assets/GooglePlayGames/ISocialPlatform/PlayGamesPlatform.cs(279,34): error CS1061: Type 'Achievement' does not contain a definition for 'TotalSteps' and no extension method 'TotalSteps' of type 'Achievement' could be found (are you missing a using directive or an assembly reference?)

Unity 4.3.3f1 (game updated from older version)
Plugin version 0.8.00 and 0.8.01

Adding support for GetUserHiResImageUri()

After adding support for GetUserHasHiResImage() I've attempted to fetch the image URI for the current authenticated user. However, looking at ADB, I get a UnityEngine AndroidJNIHelper error in the GetSignature method.

UnityEngine._AndroidJNIHelper.GetSignature (System.Object obj) [0x00000] in <filename unknown>:0 
UnityEngine._AndroidJNIHelper.GetSignature[Uri] (System.Object[] args) [0x00000] in <filename unknown>:0 
UnityEngine._AndroidJNIHelper.GetMethodID[Uri] (IntPtr jclass, System.String methodName, System.Object[] args, Boolean isStatic) [0x00000] in <filename unknown>:0 
UnityEngine.AndroidJNIHelper.GetMethodID[Uri] (IntPtr jclass, System.String methodName, System.Object[] args, Boolean isStatic) [0x00000] in <filename unknown>:0 
UnityEngine.AndroidJavaObject._Call[Uri] (System.String methodName, System.Object[] args) [0x00000] in <filename unknown>:0 
UnityEngine.AndroidJavaObject.Call[Uri] (System.String methodName, System.Object[] args) [0x00000] in <filename unknown>:0 

Modifications made in AndroidClient.cs

private void RetrieveUserInfo() {
            Logger.d("Attempting to retrieve player info.");

            using (AndroidJavaObject playerObj = mGHManager.CallGmsApi<AndroidJavaObject>(
                    "games.Games", "Players", "getCurrentPlayer")) {

                if (mUserId == null) {
                    mUserId = playerObj.Call<string>("getPlayerId");
                    Logger.d("Player ID: " + mUserId);
                }

                if (mUserDisplayName == null) {                
                    mUserDisplayName = playerObj.Call<string>("getDisplayName");
                    Logger.d("Player display name: " + mUserDisplayName);
                }

                if (mUserHasHiResImage == false) {                
                  mUserHasHiResImage = playerObj.Call<bool>("hasHiResImage");
                  Logger.d("Player has image: " + mUserHasHiResImage);
                }

                if (mUserHiResImageUri == null) {  
                  mUserHiResImageUri = playerObj.Call<Object>("getHiResImageUri");
                  Logger.d("Player image URI: " + mUserHiResImageUri.ToString());
                }
            }
        }

Is this a Unity issue or a plugin issue?

Thanks,

Ryan

PlayGamesPlatform.IsAuthenticated() Incorrect Immediately After Calling SignOut()

I found that if you call IsAuthenticated() right after calling SignOut(), IsAuthenticated will still return true. It seems that calling IsAuthenticated maybe one or more frames after calling SignOut will return the correct result.

public void SignOut()
{
    PlayGamesPlatform.Instance.SignOut();
    Debug.Log(PlayGamesPlatform.Instance.IsAuthenticated()); // returns true!
}

This is a convoluted example, but I have an event that fires in response to signing out and code listening for that event might check for authentication - it seems that the function returns an incorrect value.

I can understand if SignOut is an asynchronous function that might fail for some reason, but the interface for it suggests that you are immediately signed out.

Error building Player

Hi,

i'm having a problem when building the Android player. I did follow the documentation (readme), have the latest sdk with latest play services library installed and did the "Android Setup". I was using my own GPG package before without any problem (didn't used unity social so wanted to update to have a clean code). I'm using latest unity (4.3.1f1). Here is the error message :

Error building Player: Win32Exception: ApplicationName='C:\Program Files (x86)\Java\jre7\bin\javac.exe', CommandLine='-bootclasspath "I:/dev/android-sdk/adt-bundle-windows-x86_64-20130917/sdk/platforms/android-19\android.jar" -d "I:\dev\unity3d\projects\Hidden\Temp\StagingArea\bin\classes" -source 1.6 -target 1.6 -encoding ascii "com\google\android\gms\R.java" "com\google\example\games\basegameutils\R.java" "com\google\example\games\mainlibproj\R.java" "com\malothetoad\hidden\R.java"', CurrentDirectory='I:\dev\unity3d\projects\Hidden\Temp\StagingArea\gen'

Error when build in Unity

EntryPointNotFoundException: _SetCallbackHandlerName
AdMobPluginiOS.SetCallbackHandlerName (System.String callbackHandlerName) (at assets/Plugins/AdMobPlugin/AdMobPluginiOS.cs:36)
AdMobPlugin.SetCallbackHandlerName (System.String callbackHandlerName) (at assets/Plugins/AdMobPlugin/AdMobPlugin.cs:77)
AdMobPlugin.Awake () (at assets/Plugins/AdMobPlugin/AdMobPlugin.cs:43)

Request: Show the signed in toast for returning users also.

First off, this is an amazing plugin, thank you!

I would prefer an option to turn off the 'silent sign in' for a returning player. In most other games with Play Games it welcomes me back whenever I start the game.

I like that reminder that I'm logged in and can compare my scores with others.

Thanks!

FB plugin for Unity (5.0.3) sharing does not work on Android

I saw the fix for iOS a few threads back, but the sharing does not seem to work on Android when the FB plugin is used with the PlayGames plugin.

Thing is, the intended behavior works when I don't have the FB app installed on my Android phone. However, once I have it installed, it just asks me to login, but closes afterwards without my intended behavior.

On FB 4.3.6, the intended behavior works with the PlayGames plugin and the FB app installed, but the app crashes whenever I try to call ShowAchievementsUI() or ShowLeaderboardUI().

Edit: More details on 4.3.6, after I attempt to login once, even if I don't provide the necessary permissions, calling ShowAchievementsUI or ShowLeaderboardUI() no longer crash.

On FB 5.0.3, the intended behavior breaks with the FB app installed, but ShowAchievementsUI() or ShowLeaderboardUI() no longer crash the app.

Is this on play games end or should I open a ticket on FB side as well?

Thanks!

Small Bug List

Hey there! I have integrated your plugin into a Unity Plugin called PlayMaker. The people using it have reported a few bugs. Is there anyway I could fix these? I think they might be on your end of things?

  1. iOS only - the incorrectly drawn title box on Google Play panels. (and/or status bar showing) - not the highest priority problem for me although doesn't look great so if it can be fixed great.
  2. Android only - no 'welcome back' on sign in after closing app from multitasking and reopening (where sign in is automatic) - edit to this one. I have noticed if the app is just closed but stays active in b/g then after a long delay and returning to game you do get a 'Welcome {name}' box.
  3. iOS only - the achievement slide up panel has a transparent background(border) which turns black after completing slide up. This looks wrong and is not same as leader board slide up which has solid grey b/g as expected.
  4. Unordered lists of leaderboards and achievements. i.e. not according to the sort order given in the Google console. (1/5, 2/5 etc...) It does not work on single column displays. With double column display android phones works fine. Not with single column android or iOS. Gets order like 654123.

Any help would be great. Thank You!
img_0378
img_0379

PostprocessBuildPlayer not compatible with other plugins.

The most common way to handle this is to include a PostprocessBuildPlayer_PlayGames file that handles the specific need of this plugin and include a generic PostprocessBuildPlayer that does this:

#!/usr/bin/perl


# Post Process Build Player -- Master 
# Searches for other PostprocessBuildPlayer scripts and executes them. Make sure the other script
# have a name suffix with an underscore "_" like "PostprocessBuildPlayer_AnotherBuild" or whatever.
#
# Based on script by Rob Terrell, [email protected]

use File::Glob ':glob';

# Grab all the PostprocessBuildPlayer files
@files = bsd_glob( "Assets/Editor/postprocessbuildplayer_*", GLOB_NOCASE );

foreach $file( @files )
{
    if( !( $file =~ m/\./ ) )
    {
        system( "chmod", "755", $file );
        print "PostProcessBuildPlayer: calling " . $file . "\n";
        system( $file, $ARGV[0], $ARGV[1], $ARGV[2], $ARGV[3], $ARGV[4], $ARGV[5], $ARGV[6] );

        if ( $? == -1 )
        {
          print "command failed: $!\n";
        }
        else
        {
          printf "command exited with value %d", $? >> 8;
        }
    }
}

iOS: GetUserId has Null Exception, Leads to Crash

I noticed that sometimes when I call GetUserId, the game crashes with a stack trace something like this:

thread #1: tid = 0xb1b52, 0x38657b26 libobjc.A.dylib`objc_msgSend + 6, queue = 'com.apple.main-thread, stop reason = EXC_BAD_ACCESS (code=1, address=0xc)
    frame #0: 0x38657b26 libobjc.A.dylib`objc_msgSend + 6
    frame #1: 0x00a08bd0 ttgame`_NSStringToUTF8Buf(s=0x1b1f80b0, buf=0x1853bc00, bufSize=512) + 116 at GPGSInterface.m:40
    frame #2: 0x00a08d7c ttgame`GPGSGetPlayerId(buf=0x1853bc00, bufSize=512) + 124 at GPGSInterface.m:51
    frame #3: 0x0032e948 ttgame`m_3059 + 80
    frame #4: 0x0014ea0c ttgame`m_GooglePlayGames_IOS_IOSClient_GetUserId + 120
    frame #5: 0x0014c2e8 ttgame`m_GooglePlayGames_PlayGamesPlatform_GetUserId + 148

Upon closer inspection using some breakpoints and watch variables, it seems that GPGSManager.m saves pointers to the player name and ID around line 85. However, the GPGPlayer instance is being deallocated after those variables are saved, which leaves them set to 'nil'. Then, any further call to GetUserId will trigger a null exception when copying the string.

Not sure what the core solution is here - it seems that the GPGPlayer instance should remain until the app quits or the user signs out, but maybe that's not how the system is meant to work. If GPGPlayer can be deallocated, it makes sense then to either copy the name/ID without using a pointer, or fetch a new instance of GPGPlayer anytime you want to retrieve data from it.

How to catch a Manual Log out event ?

Hi guys,

Since logged-in players can go to Settings and manually sign themselves out of the system, how can we catch this event so we can redirect them back to the login phase ?

Thanks in advance !

/Unity (18399): AndroidJavaException: java.lang.IllegalStateException: A required meta-data tag in your app's AndroidManifest.xml does not exist.

Hi,

I downloaded the plugin, install went smoothly, I created the related google play service in my console for testing did all the necessary setup, etc, and now when I call the Authenticate method...nothing happens.

I'm using the latest version of Unity, 4.3.3 and its on a 2d game.

EDIT:

Ran adb logcat, got this problem:

I/Unity (18399): AndroidJavaException: java.lang.IllegalStateException: A required meta-data tag in your app's AndroidManifest.xml does not exist. You must have the following declaration within the element: <meta-data android:name="com.google.android.gms.version" android:value
@integer/google_play_services_version" />

what is problem?

what is problem?

android build and run and error

if (!Social.localUser.authenticated) {
// Authenticate
Social.localUser.Authenticate((bool success) => {
Debug.Log(success ? "Successfully authenticated" : "Authentication failed.");
} );
}

02-27 22:16:11.131: I/Unity(6153): Exception: No such proxy method: UnityEngine.AndroidJavaRunnableProxy.run()
02-27 22:16:11.131: I/Unity(6153): at UnityEngine.AndroidJavaProxy.Invoke (System.String methodName, System.Object[] args) [0x00000] in :0
02-27 22:16:11.131: I/Unity(6153): at UnityEngine.AndroidJavaProxy.Invoke (System.String methodName, UnityEngine.AndroidJavaObject[] javaArgs) [0x00000] in :0
02-27 22:16:11.131: I/Unity(6153): at UnityEngine._AndroidJNIHelper.InvokeJavaProxyMethod (UnityEngine.AndroidJavaProxy proxy, IntPtr jmethodName, IntPtr jargs) [0x00000] in :0
02-27 22:16:11.131: I/Unity(6153):
02-27 22:16:11.131: I/Unity(6153): (Filename: Line: -1)
02-27 22:16:11.131: I/Unity(6153): Exception: No such proxy method: UnityEngine.AndroidJavaRunnableProxy.run()
02-27 22:16:11.131: I/Unity(6153): at UnityEngine.AndroidJavaProxy.Invoke (System.String methodName, System.Object[] args) [0x00000] in :0
02-27 22:16:11.131: I/Unity(6153): at UnityEngine.AndroidJavaProxy.Invoke (System.String methodName, UnityEngine.AndroidJavaObject[] javaArgs) [0x00000] in :0
02-27 22:16:11.131: I/Unity(6153): at UnityEngine._AndroidJNIHelper.InvokeJavaProxyMethod (UnityEngine.AndroidJavaProxy proxy, IntPtr jmethodName, IntPtr jargs) [0x00000] in :0

Google Play services is missing - error dialog does not appear

01-03 12:27:59.867: W/GooglePlayServicesUtil(19130): Google Play services is missing.
01-03 12:27:59.887: E/WindowManager(19130): Activity com.google.example.games.pluginsupport.SignInHelperActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@2b041798 that was originally added here
01-03 12:27:59.887: E/WindowManager(19130): android.view.WindowLeaked: Activity com.google.example.games.pluginsupport.SignInHelperActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@2b041798 that was originally added here
01-03 12:27:59.887: E/WindowManager(19130): at android.view.ViewRoot.(ViewRoot.java:267)
01-03 12:27:59.887: E/WindowManager(19130): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:148)
01-03 12:27:59.887: E/WindowManager(19130): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
01-03 12:27:59.887: E/WindowManager(19130): at android.view.Window$LocalWindowManager.addView(Window.java:424)
01-03 12:27:59.887: E/WindowManager(19130): at android.app.Dialog.show(Dialog.java:241)
01-03 12:27:59.887: E/WindowManager(19130): at com.google.example.games.basegameutils.GameHelper.showFailureDialog(GameHelper.java:998)
01-03 12:27:59.887: E/WindowManager(19130): at com.google.example.games.basegameutils.GameHelper.beginUserInitiatedSignIn(GameHelper.java:649)
01-03 12:27:59.887: E/WindowManager(19130): at com.google.example.games.pluginsupport.SignInHelperActivity.onSignInFailed(SignInHelperActivity.java:65)
01-03 12:27:59.887: E/WindowManager(19130): at com.google.example.games.basegameutils.GameHelper.notifyListener(GameHelper.java:609)
01-03 12:27:59.887: E/WindowManager(19130): at com.google.example.games.basegameutils.GameHelper.onConnectionFailed(GameHelper.java:869)
01-03 12:27:59.887: E/WindowManager(19130): at com.google.android.gms.internal.de.a(Unknown Source)
01-03 12:27:59.887: E/WindowManager(19130): at com.google.android.gms.internal.em.a(Unknown Source)
01-03 12:27:59.887: E/WindowManager(19130): at com.google.android.gms.internal.de$a.handleMessage(Unknown Source)
01-03 12:27:59.887: E/WindowManager(19130): at android.os.Handler.dispatchMessage(Handler.java:99)
01-03 12:27:59.887: E/WindowManager(19130): at android.os.Looper.loop(Looper.java:130)
01-03 12:27:59.887: E/WindowManager(19130): at android.app.ActivityThread.main(ActivityThread.java:3701)
01-03 12:27:59.887: E/WindowManager(19130): at java.lang.reflect.Method.invokeNative(Native Method)
01-03 12:27:59.887: E/WindowManager(19130): at java.lang.reflect.Method.invoke(Method.java:507)
01-03 12:27:59.887: E/WindowManager(19130): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)
01-03 12:27:59.887: E/WindowManager(19130): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:624)
01-03 12:27:59.887: E/WindowManager(19130): at dalvik.system.NativeStart.main(Native Method)

Minimal Sample - "Network Error" Popup appears and disappears quickly when airplane mode is on

When I run the Minimal sample, turn Airplane mode on, and then hit Authenticate, it very briefly pops up a message that says, "Failed to sign in. Please check your network connection and try again.". Almost as soon as it appears, it then disappears and we're returned to the main screen with the button and "Authentication failed" at the top.

Obviously it should fail to Authenticate, but I'm wondering why this brief popup is appearing. Is it something we can turn off? For a game we're working on, we'd like to try and Authenticate and, if it's not able to, deal with it by entering offline mode. But, we don't want to see a popup appear - especially one that doesn't last long enough for the user to read.

I'm running the sample on a Nexus 7 (1st generation), running Android 4.4.2.

Missing File: GPGSParams.h

When build the game to IOS is missing the GPGSParams.h file:

FATAL ERROR: Failed to read GPGSParams.h

Incompatible with admob sdk

The plugin is great but its incompatible with admob's sdk jar file. when I put both of the in the android folder I get the following error message. but when I delete the sdk file (GoogleAdMobAdsSdk-6.4.1.jar) the problem is resolved but I can't use admob any more.

Error building Player: CommandInvokationFailure: Unable to convert classes into dex format. See the Console for details.
/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home/bin/java -Xmx1024M -Dcom.android.sdkmanager.toolsdir="/Users/Nima/Software/Development/android-sdk/tools" -Dfile.encoding=UTF8 -jar "/Applications/Unity/Unity.app/Contents/BuildTargetTools/AndroidPlayer/sdktools.jar" -

regards

FR: provide way to inhibit achievement popups

I have my own custom achievement dialogs that come up, and I want to disable the ones this library pops up. If I can't do that, I would want to be able to use something like setGravityForPopups, so they can be shown on the bottom of the screen. I don't want them to be shown at the top of the screen because that would negatively impact gameplay. Is there any way that could be done or any way it could be added?

Does not work with Unity Facebook Plugin

The GPGS plugin does not play nicely (no pun intended) with the FB plugin. This is due to the takeover of the 'openUrl' call in the GPGSAppController class, which is not integrated into Unity's UnityAppController openUrl delegation strategy. Seems to affect all versions, but I am using FB Unity plugin beta 5.03.

GooglePlus.h not found / PlayGameServices.h not found.

I've work hours on this now. I think I've run out of ideas on how to fix this.

GPGSAppController.m
Lexical or Preprocessor Issue
'GooglePlus/GooglePlus.h' file not found

GPGSAchOrLbDelegate.h
Lexical or Preprocessor Issue
'PlayGameServices/PlayGameServices.h' file not found

It looks to me like the Frameworks are not being seen. But I can't find anything else to do, I've tried it all.

Everything is set up correctly, for iOS in Unity. I've built to an Xcode project, I've added every Framework listed in the documentation.

I dragged the 5 files to the project:
GoogleOpenSource.framework
GooglePlus.bundle
GooglePlus.framework
PlayGameServices.bundle
PlayGameServices.framework

I've double/triple/quadruple checked that they ARE included in Build Phases -> Link Binary With Libraries.

The .bundles are also in the project.

I've added the -ObjC flag to the Other Linker Flags.

Latest OS X Mavericks and Latest Xcode 5.0.2

I've wiped, re-uilt, re-created the xcode project, cleaned, built. Done everything at least 5 times over. Clean checkout from my repository and did it again. Clean install of Unity. Simulator and device builds, with the correct choice in Unity beforehand. Every possible thing I can think of. But it just comes down to an error while compiling because it can't find the .h files. Which has to mean the framework isn't linking. I've reached the end of my ideas.

Am I missing something really trivial and stupid?

Thank you for any help you can give me. This works great on Android, I published a game with it two weeks ago, and am in the Top 10 New Apps and Games in Canada! I'd like to get it running on iOS now.

Thanks!

AddressBook.framework

Hi,

First off, thanks for creating this plugin.

Just thought I'd mention that to get this running on iOS, I also needed to add AddressBook.framework to the project.

I was receiving errors such as

Undefined symbols for architecture armv7:
  "_kABPersonLastNameProperty", referenced from:
      ___48+[GPPAddressBook loadDeviceContactsWithHandler:]_block_invoke in GooglePlus(GPPAddressBook.o)
  "_kABPersonFirstNameProperty", referenced from:
      ___48+[GPPAddressBook loadDeviceContactsWithHandler:]_block_invoke in GooglePlus(GPPAddressBook.o)
  "_ABAddressBookGetPersonCount", referenced from:
      ___48+[GPPAddressBook loadDeviceContactsWithHandler:]_block_invoke in GooglePlus(GPPAddressBook.o)
  "_kABPersonEmailProperty", referenced from:
      ___48+[GPPAddressBook loadDeviceContactsWithHandler:]_block_invoke in GooglePlus(GPPAddressBook.o)
  "_ABAddressBookCopyArrayOfAllPeople", referenced from:
      ___48+[GPPAddressBook loadDeviceContactsWithHandler:]_block_invoke in GooglePlus(GPPAddressBook.o)
  "_ABMultiValueGetCount", referenced from:
      ___48+[GPPAddressBook loadDeviceContactsWithHandler:]_block_invoke in GooglePlus(GPPAddressBook.o)
  "_ABRecordCopyValue", referenced from:
      ___48+[GPPAddressBook loadDeviceContactsWithHandler:]_block_invoke in GooglePlus(GPPAddressBook.o)
  "_ABMultiValueCopyValueAtIndex", referenced from:
      ___48+[GPPAddressBook loadDeviceContactsWithHandler:]_block_invoke in GooglePlus(GPPAddressBook.o)
  "_ABPersonCopyImageDataWithFormat", referenced from:
      ___48+[GPPAddressBook loadDeviceContactsWithHandler:]_block_invoke in GooglePlus(GPPAddressBook.o)
  "_ABAddressBookCreateWithOptions", referenced from:
      +[GPPAddressBook loadDeviceContactsWithHandler:] in GooglePlus(GPPAddressBook.o)
  "_ABPersonHasImageData", referenced from:
      ___48+[GPPAddressBook loadDeviceContactsWithHandler:]_block_invoke in GooglePlus(GPPAddressBook.o)
  "_ABAddressBookRequestAccessWithCompletion", referenced from:
      +[GPPAddressBook loadDeviceContactsWithHandler:] in GooglePlus(GPPAddressBook.o)
ld: symbol(s) not found for architecture armv7
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Adding the AddressBook.framework solved these issues. Does it need to be added to the list of required frameworks in the readme file?

Thanks,

Owen

Show a particular Leaderboard problem

The documentation wrote this:

using GooglePlayGames;
using UnityEngine.SocialPlatforms;
...
// show leaderboard UI
(PlayGamesPlatform) Social.Active).ShowLeaderboardUI("Cfji293fjsie_QA");

That last line of code raised an error when compiled. How can I fix it ? Thanks in advance !

Add Account Crashes the App [13400701]

Hello again,

In the latest version of the plugin (it worked fine in 0.8.00), I'm finding that when authenticating and being presented with the account chooser on Android, the game will crash if you choose the "Add Account" option. The crash occurs if I wait a moment after opening the AddAccount activity.

Here is the crash log associated with the issue. So far, it has been 100% reproducible on my device.

I/ActivityManager(  764): START u0 {flg=0x80000 cmp=com.google.android.gsf.login/.AccountIntroActivity (has extras)} from pid 2256
I/ActivityManager(  764): Start proc com.google.android.gsf.login for activity com.google.android.gsf.login/.AccountIntroActivity: pid=3535 uid=10007 gids={50007, 3003, 1007, 3002, 3001, 1028, 1015, 2001, 3006, 3007}
I/GLSActivity( 3535): Starting account intro Intent { flg=0x80000 cmp=com.google.android.gsf.login/.AccountIntroActivity (has extras) }
I/ActivityManager(  764): START u0 {cmp=com.google.android.gsf.login/.AccountIntroUIActivity (has extras)} from pid 3535
I/Adreno-EGL( 3535): <qeglDrvAPI_eglInitialize:320>: EGL 1.4 QUALCOMM Build: I0404c4692afb8623f95c43aeb6d5e13ed4b30ddbDate: 11/06/13
I/ActivityManager(  764): Displayed com.google.android.gsf.login/.AccountIntroUIActivity: +162ms (total +360ms)
I/Choreographer( 3368): Skipped 118 frames!  The application may be doing too much work on its main thread.
D/AppStateService( 1065): client connected with version: 4242000
W/ContextImpl( 1065): Implicit intents with startService are not safe: Intent { act=com.google.android.gms.plus.service.default.INTENT } android.content.ContextWrapper.startService:494 com.google.android.gms.plus.service.DefaultIntentService.a:29 fny.a:264 
D/AndroidRuntime( 3368): Shutting down VM
W/dalvikvm( 3368): threadid=1: thread exiting with uncaught exception (group=0x420f1ba8)
E/AndroidRuntime( 3368): FATAL EXCEPTION: main
E/AndroidRuntime( 3368): Process: <REMOVED>, PID: 3368
E/AndroidRuntime( 3368): java.lang.Error: FATAL EXCEPTION [main]
E/AndroidRuntime( 3368): Unity version     : 4.3.2f1
E/AndroidRuntime( 3368): Device model      : LGE Nexus 5
E/AndroidRuntime( 3368): Device fingerprint: google/hammerhead/hammerhead:4.4.2/KOT49H/937116:user/release-keys
E/AndroidRuntime( 3368): 
E/AndroidRuntime( 3368): Caused by: java.lang.NullPointerException
E/AndroidRuntime( 3368):    at com.google.android.gms.common.ConnectionResult.startResolutionForResult(Unknown Source)
E/AndroidRuntime( 3368):    at com.google.example.games.basegameutils.GameHelper.resolveConnectionResult(GameHelper.java:752)
E/AndroidRuntime( 3368):    at com.google.example.games.basegameutils.GameHelper.onConnectionFailed(GameHelper.java:729)
E/AndroidRuntime( 3368):    at com.google.android.gms.internal.dx.a(Unknown Source)
E/AndroidRuntime( 3368):    at com.google.android.gms.common.api.GoogleApiClient.bn(Unknown Source)
E/AndroidRuntime( 3368):    at com.google.android.gms.common.api.GoogleApiClient.f(Unknown Source)
E/AndroidRuntime( 3368):    at com.google.android.gms.common.api.GoogleApiClient$4.onConnectionFailed(Unknown Source)
E/AndroidRuntime( 3368):    at com.google.android.gms.internal.dx.a(Unknown Source)
E/AndroidRuntime( 3368):    at com.google.android.gms.internal.dw$h.b(Unknown Source)
E/AndroidRuntime( 3368):    at com.google.android.gms.internal.dw$h.b(Unknown Source)
E/AndroidRuntime( 3368):    at com.google.android.gms.internal.dw$b.bR(Unknown Source)
E/AndroidRuntime( 3368):    at com.google.android.gms.internal.dw$a.handleMessage(Unknown Source)
E/AndroidRuntime( 3368):    at android.os.Handler.dispatchMessage(Handler.java:102)
E/AndroidRuntime( 3368):    at android.os.Looper.loop(Looper.java:136)
E/AndroidRuntime( 3368):    at android.app.ActivityThread.main(ActivityThread.java:5017)
E/AndroidRuntime( 3368):    at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime( 3368):    at java.lang.reflect.Method.invoke(Method.java:515)
E/AndroidRuntime( 3368):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
E/AndroidRuntime( 3368):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
E/AndroidRuntime( 3368):    at dalvik.system.NativeStart.main(Native Method)

The line mentioned in the error (GameHelper.java line 752) seems to be returning a result to GameHelperListener instance in Unity. Maybe the listener is unexpectedly null or something?

FR: AdMob support

AdMob is now also part of Google Play Services. Are there plans to add this in this plugin?

@synthesize of weak property

I have followed all the instructions to compile for iOS. I still receive

Error: synthesize of 'weak' property is only allowed in ARC or GC mode.

I have switched to ARC mode but that generates about 20 more errors.

Any ideas? I am using the latest version of Unity.

Missing tags from Android manifest [includes fix]

[NOTE by btco@: this fix may be necessary if you are writing your own customized AndroidManifest.xml file, and getting errors about certain meta-data tags being missing from it]

While trying to play with the launcher, the debug logs were telling me that a tag was missing from the manifest file:

I manually added the tag to the manifest file generated in the staging area and rebuilt the game. I am not receiving that error message anymore, but every time I try to authenticate the game crashes (twlauncher not responding).

Not sure what's going on...

Accessing Auth Token?

Is there any way to access the Auth Token that was used when authenticating the user? I need to use it to authenticate the user with my own server.

iOS - Terminating with uncaught exception

Hello,

When i call PlayGamesPlatform.Activate(); on iOS i get the following error:
libc++abi.dylib: terminating with uncaught exception of type NSException
Stacktrace:

at (wrapper managed-to-native) GooglePlayGames.IOS.IOSClient.GPGSAuthenticateWithCallback (GooglePlayGames.IOS.IOSClient/GPGSSuccessCallback) <0xffffffff>

With Android it works perfectly!

I added all the necessary frameworks and bundles.

Kind regards,
Gjjansen

Error:Exception: JNI: Init'd AndroidJavaClass with null ptr!

Code:
internal AndroidJavaObject GetActivity() {

        AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
        if (jc == null) {
            throw new System.Exception("Could not get class com.unity3d.player.UnityPlayer.");
        }
        AndroidJavaObject activity = jc.GetStatic<AndroidJavaObject>("currentActivity");
        if (activity == null) {
            throw new System.Exception("Could not get class current activity from UnityPlayer.");
        }
        return activity;
    }

Error:Exception: JNI: Init'd AndroidJavaClass with null ptr!

FR: Move the top-level Google Play Games menu

Thanks for making this, it's good to have offically-supported repos.

But could you move the GPG menu inside Window, or Assets? I only need it once at the start of a project and then it sits there taking up real estate.

Invalid Status Bar position [13400041]

When I show a leaderboard (on iOS) it's showing the status bar at the top of the page and the settings icon and 'done' button as well as title are positioned strangely, sitting on top of a half height box. I've attached an image to show you.

img_0378

Error Exception: JNI: Init'd AndroidJavaClass with null ptr!

code:
internal AndroidJavaObject GetActivity() {

        AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
        if (jc == null) {
            throw new System.Exception("Could not get class com.unity3d.player.UnityPlayer.");
        }
        AndroidJavaObject activity = jc.GetStatic<AndroidJavaObject>("currentActivity");
        if (activity == null) {
            throw new System.Exception("Could not get class current activity from UnityPlayer.");
        }
        return activity;
    }

problem:
Exception: JNI: Init'd AndroidJavaClass with null ptr!
UnityEngine.AndroidJavaClass..ctor (IntPtr jclass)
UnityEngine.AndroidJavaObject.get_JavaLangClass ()
UnityEngine.AndroidJavaObject.FindClass (System.String name)
UnityEngine.AndroidJavaClass._AndroidJavaClass (System.String className)
UnityEngine.AndroidJavaClass..ctor (System.String className)
GooglePlayGames.Android.AndroidClient.GetActivity () (at assets/GooglePlayGames/Platforms/Android/AndroidClient.cs:271)
GooglePlayGames.Android.AndroidClient.RunOnUiThread (System.Action action) (at assets/GooglePlayGames/Platforms/Android/AndroidClient.cs:283)
GooglePlayGames.Android.AndroidClient..ctor () (at assets/GooglePlayGames/Platforms/Android/AndroidClient.cs:63)
GooglePlayGames.PlayGamesClientFactory.GetPlatformPlayGamesClient () (at assets/GooglePlayGames/Platforms/PlayGamesClientFactory.cs:26)
GooglePlayGames.PlayGamesPlatform.Authenticate (ILocalUser unused, System.Action1 callback, Boolean silent) (at assets/GooglePlayGames/ISocialPlatform/PlayGamesPlatform.cs:157) GooglePlayGames.PlayGamesPlatform.Authenticate (ILocalUser localUser, System.Action1 callback) (at assets/GooglePlayGames/ISocialPlatform/PlayGamesPlatform.cs:132)
GooglePlayGames.PlayGamesLocalUser.Authenticate (System.Action`1 callback) (at assets/GooglePlayGames/ISocialPlatform/PlayGamesLocalUser.cs:36)
Game6_Player.Start () (at assets/game 6/script/Game6_Player.cs:124)

Using Ads gets me a "Resources were not found"

Hey,

If I use this plugin and display ads, they display correctly and work, but I get the error message in logcat each time the ad is refreshed:
"E/GooglePlayServicesUtil( 6204): The Google Play services resources were not found. Check your project configuration to ensure that the resources are included."
3 times in a row, at each ad refresh.

I've tried exporting the project and build with Eclipse as well, it's the same issue. I don't understand, as the Google Play Services resources are indeed in the apk generated by Unity or Eclipse. I used apktool to look at the resources and they're here. I've checked the Eclipse generated R.java files, they all list the proper resources.

Is the issue with the google play services lib itself, like some resources are missing from it only for Ads ?

Thank you for your help.

Error when build in Xcode:Undefined symbols for architecture armv7

Undefined symbols for architecture armv7:
"OBJC_CLASS$_CTTelephonyNetworkInfo", referenced from:
objc-class-ref in libGoogleAdMobAds.a(GADDevice.o)
ld: symbol(s) not found for architecture armv7
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Cancel login requires performing the action twice [13400167]

Update to 0.8.01 has introduced a bug which can be recreated using the Minimal example project, experienced on Nexus 5/7.

Using the old 0.8.0 version

  • Click authenticate
  • wait for sign in prompt
  • hit cancel
  • Sign in prompt closes

Using the new 0.8.01

  • Click authenticate
  • wait for sign in prompt
  • hit cancel
  • Sign in prompt closes, and another sign in prompt immediately displays
  • hit cancel
  • Sign in prompt closes successfully

Authenticate can be clicked again and the same bug appears maybe 3 or four times before returning to normal behaviour.

iOS GPGSAppController.m Causes Issues with Other Plugins

I was having an issue where my Facebook authentication method stopped working after adding the Google Play Games plugin. Upon further inspection, I found the problem was that this plugin extends UnityAppController and overrides the application:openURL method without calling the base implementation, which my Facebook plugin relies on.

There doesn't seem to be any harm in calling the base implementation, and it ensures that any other plugins relying on the default behavior function correctly. Here's the change I made in GPGSAppController.m:

- (BOOL)application:(UIApplication *)application
            openURL:(NSURL *)url
  sourceApplication:(NSString *)sourceApplication
         annotation:(id)annotation {

    NSLog(@"Calling super implementation of openURL.");
    [super application:application openURL:url sourceApplication:sourceApplication annotation:annotation];

    return [GPPURLHandler handleURL:url
                  sourceApplication:sourceApplication
                         annotation:annotation];
}

As an extension of this, it would be ideal if the plugin didn't override UnityAppController, as that can potentially clash with other plugins - but I'm not too good with Obj-C or native iOS development, so maybe it isn't so easy.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.