### Start Discovering Nearby Devices Source: https://context7.com/playgameservices/play-games-plugin-for-unity/llms.txt Starts discovering nearby devices that are advertising. Discovery runs indefinitely until stopped. ```csharp public void StartDiscovery() { nearbyClient.StartDiscovery( nearbyClient.GetServiceId(), TimeSpan.FromSeconds(0), // Discover indefinitely this); } ``` -------------------------------- ### Start Advertising for Nearby Connections Source: https://context7.com/playgameservices/play-games-plugin-for-unity/llms.txt Starts advertising the device to nearby devices. It accepts connection requests and automatically accepts them with a welcome message. ```csharp public void StartAdvertising() { List appIds = new List { nearbyClient.GetAppBundleId() }; nearbyClient.StartAdvertising( "Player_" + UnityEngine.Random.Range(1000, 9999), appIds, TimeSpan.FromSeconds(0), // Advertise indefinitely result => { Debug.Log("Advertising started: " + result.Status); }, request => { Debug.Log("Connection request from: " + request.RemoteEndpoint.Name); // Accept the connection nearbyClient.AcceptConnectionRequest( request.RemoteEndpoint.EndpointId, Encoding.UTF8.GetBytes("Welcome!"), this); }); } ``` -------------------------------- ### Load Leaderboard Scores in Unity Source: https://context7.com/playgameservices/play-games-plugin-for-unity/llms.txt Loads scores from a leaderboard with configurable parameters for collection, time span, and starting position. Requires setup of PlayGamesPlatform and relevant using statements. ```csharp using GooglePlayGames; using GooglePlayGames.BasicApi; using UnityEngine; using UnityEngine.SocialPlatforms; public class LeaderboardDataLoader : MonoBehaviour { private const string LEADERBOARD_ID = "CgkI...BQAQ"; private LeaderboardScoreData currentScoreData; public void LoadPublicTopScores() { PlayGamesPlatform.Instance.LoadScores( LEADERBOARD_ID, LeaderboardStart.TopScores, 25, // number of scores to load LeaderboardCollection.Public, LeaderboardTimeSpan.AllTime, data => { if (data.Valid) { Debug.Log("Loaded " + data.Scores.Length + " scores"); Debug.Log("Approximate total count: " + data.ApproximateCount); foreach (IScore score in data.Scores) { Debug.Log(score.rank + ". " + score.userID + ": " + score.value); } currentScoreData = data; } else { Debug.LogError("Failed to load scores: " + data.Status); } }); } public void LoadPlayerCenteredScores() { PlayGamesPlatform.Instance.LoadScores( LEADERBOARD_ID, LeaderboardStart.PlayerCentered, 25, LeaderboardCollection.Public, LeaderboardTimeSpan.Weekly, data => { Debug.Log("Player-centered scores loaded: " + data.Valid); currentScoreData = data; }); } public void LoadFriendsScores() { PlayGamesPlatform.Instance.LoadScores( LEADERBOARD_ID, LeaderboardStart.TopScores, 25, LeaderboardCollection.Social, // Friends only LeaderboardTimeSpan.AllTime, data => { Debug.Log("Friends scores loaded: " + data.Valid); }); } public void LoadMoreScores() { if (currentScoreData?.NextPageToken == null) { Debug.Log("No more scores to load"); return; } PlayGamesPlatform.Instance.LoadMoreScores( currentScoreData.NextPageToken, 10, data => { if (data.Valid) { Debug.Log("Loaded " + data.Scores.Length + " more scores"); currentScoreData = data; } }); } } ``` -------------------------------- ### Initialize Nearby Connections Client Source: https://context7.com/playgameservices/play-games-plugin-for-unity/llms.txt Initializes the Nearby Connections client and logs its maximum payload sizes. This should be called during application startup. ```csharp void Start() { PlayGamesPlatform.InitializeNearby(client => { nearbyClient = client; Debug.Log("Nearby initialized!"); Debug.Log("Max reliable payload: " + client.MaxReliableMessagePayloadLength()); Debug.Log("Max unreliable payload: " + client.MaxUnreliableMessagePayloadLength()); }); } ``` -------------------------------- ### Display Leaderboard UI in Unity Source: https://context7.com/playgameservices/play-games-plugin-for-unity/llms.txt Displays the built-in Google Play Games leaderboard UI with optional filtering. Requires relevant using statements. ```csharp using GooglePlayGames; using GooglePlayGames.BasicApi; using UnityEngine; public class LeaderboardUI : MonoBehaviour { private const string LEADERBOARD_HIGH_SCORES = "CgkI...BQAQ"; public void ShowAllLeaderboards() { // Show all available leaderboards Social.ShowLeaderboardUI(); } public void ShowSpecificLeaderboard() { // Show a specific leaderboard PlayGamesPlatform.Instance.ShowLeaderboardUI(LEADERBOARD_HIGH_SCORES); } public void ShowLeaderboardWithTimeSpan() { // Show leaderboard filtered by time span PlayGamesPlatform.Instance.ShowLeaderboardUI( LEADERBOARD_HIGH_SCORES, LeaderboardTimeSpan.Weekly, status => { Debug.Log("Leaderboard UI closed with status: " + status); }); } public void SetDefaultLeaderboard() { // Set the default leaderboard shown when calling ShowLeaderboardUI() PlayGamesPlatform.Instance.SetDefaultLeaderboardForUI(LEADERBOARD_HIGH_SCORES); } } ``` -------------------------------- ### Activate Play Games Platform and Authenticate User Source: https://context7.com/playgameservices/play-games-plugin-for-unity/llms.txt Activates the Play Games platform and attempts automatic user sign-in. Call this before using any Play Games features. Debug logging can be enabled optionally. ```csharp using GooglePlayGames; using GooglePlayGames.BasicApi; using UnityEngine; public class GameManager : MonoBehaviour { void Start() { // Enable debug logging (optional) PlayGamesPlatform.DebugLogEnabled = true; // Activate Play Games Platform PlayGamesPlatform.Activate(); // Authenticate the user (automatic sign-in attempt) PlayGamesPlatform.Instance.Authenticate(OnSignInResult); } private void OnSignInResult(SignInStatus signInStatus) { if (signInStatus == SignInStatus.Success) { Debug.Log("Authenticated! Hello, " + Social.localUser.userName); Debug.Log("User ID: " + Social.localUser.id); } else { Debug.Log("Authentication failed: " + signInStatus); } } } ``` -------------------------------- ### Build Play Games Plugin Shared Library Source: https://github.com/playgameservices/play-games-plugin-for-unity/blob/master/SupportFiles/Public/PlayGamesPluginSupport/CMakeLists.txt Creates a shared library for the Play Games plugin, compiling bridge.cc and plugin_shim.cc. ```cmake add_library(gpg SHARED src/main/cpp/bridge.cc src/main/cpp/plugin_shim.cc ) ``` -------------------------------- ### Configure Play Games SDK Library Source: https://github.com/playgameservices/play-games-plugin-for-unity/blob/master/SupportFiles/Public/PlayGamesPluginSupport/CMakeLists.txt Defines the static Play Games SDK library and sets its import location based on the Android ABI. ```cmake cmake_minimum_required(VERSION 3.4.1) add_library(gpg_sdk STATIC IMPORTED) set_target_properties(gpg_sdk PROPERTIES IMPORTED_LOCATION ${GPG_SDK_PATH}/lib/c++/${ANDROID_ABI}/libgpg.a) ``` -------------------------------- ### Open Saved Game with Manual Conflict Resolution Source: https://context7.com/playgameservices/play-games-plugin-for-unity/llms.txt Opens a saved game with manual conflict resolution, allowing custom logic for merging conflicts. Requires implementing `HandleConflict` and `HandleOpenCompleted` callbacks. The `prefetchDataOnConflict` parameter should be set to `true` to enable conflict data fetching. ```csharp using GooglePlayGames; using GooglePlayGames.BasicApi; using GooglePlayGames.BasicApi.SavedGame; using UnityEngine; using System.Text; public class ManualConflictResolutionManager : MonoBehaviour { private ISavedGameMetadata currentSavedGame; public void OpenWithManualResolution(string filename) { ISavedGameClient savedGameClient = PlayGamesPlatform.Instance.SavedGame; savedGameClient.OpenWithManualConflictResolution( filename, DataSource.ReadNetworkOnly, true, // prefetchDataOnConflict HandleConflict, HandleOpenCompleted); } private void HandleConflict( IConflictResolver resolver, ISavedGameMetadata original, byte[] originalData, ISavedGameMetadata unmerged, byte[] unmergedData) { Debug.Log("Conflict detected!"); Debug.Log("Original: " + original.Description); Debug.Log("Original data: " + Encoding.UTF8.GetString(originalData)); Debug.Log("Unmerged: " + unmerged.Description); Debug.Log("Unmerged data: " + Encoding.UTF8.GetString(unmergedData)); // Option 1: Choose one of the existing saves // resolver.ChooseMetadata(original); // resolver.ChooseMetadata(unmerged); // Option 2: Merge the data and create a new save string mergedData = MergeGameData( Encoding.UTF8.GetString(originalData), Encoding.UTF8.GetString(unmergedData)); var updateBuilder = new SavedGameMetadataUpdate.Builder() .WithUpdatedDescription("Merged save: " + DateTime.Now); resolver.ResolveConflict( original, updateBuilder.Build(), Encoding.UTF8.GetBytes(mergedData)); } private void HandleOpenCompleted(SavedGameRequestStatus status, ISavedGameMetadata game) { if (status == SavedGameRequestStatus.Success) { Debug.Log("Saved game opened (conflicts resolved if any)"); currentSavedGame = game; } else { Debug.LogError("Failed to open saved game: " + status); } } private string MergeGameData(string original, string unmerged) { // Implement your custom merge logic here // For example, take the higher score from each save return original; // Simplified example } } ``` -------------------------------- ### Link Play Games Plugin Libraries Source: https://github.com/playgameservices/play-games-plugin-for-unity/blob/master/SupportFiles/Public/PlayGamesPluginSupport/CMakeLists.txt Links the necessary libraries for the Play Games plugin, including gpg_sdk, android, and log. ```cmake target_link_libraries(gpg gpg_sdk android log) ``` -------------------------------- ### Fetch Player Stats Source: https://context7.com/playgameservices/play-games-plugin-for-unity/llms.txt Retrieves player statistics such as session counts and engagement metrics. Requires the player to be signed in. ```csharp using GooglePlayGames; using GooglePlayGames.BasicApi; using GooglePlayGames.ISocialPlatform; using UnityEngine; public class PlayerStatsManager : MonoBehaviour { void FetchPlayerStats() { PlayGamesPlatform.Instance.GetPlayerStats((statusCode, stats) => { if (statusCode == CommonStatusCodes.Success) { Debug.Log("Player Stats Retrieved!"); Debug.Log("Number of Sessions: " + stats.NumberOfSessions); Debug.Log("Days Since Last Played: " + stats.DaysSinceLastPlayed); Debug.Log("Number of Purchases: " + stats.NumberOfPurchases); Debug.Log("Session Percentile: " + stats.SessionPercentile); Debug.Log("Spend Percentile: " + stats.SpendPercentile); } else if (statusCode == CommonStatusCodes.SignInRequired) { Debug.LogError("Player must be signed in to get stats."); } else { Debug.LogError("Failed to get player stats: " + statusCode); } }); } } ``` -------------------------------- ### Show Saved Game UI and Fetch All Saved Games in Unity Source: https://context7.com/playgameservices/play-games-plugin-for-unity/llms.txt Displays the saved game selection UI, allowing users to select, create, or delete saved games. Also fetches all available saved games from the network. ```csharp using GooglePlayGames; using GooglePlayGames.BasicApi; using GooglePlayGames.BasicApi.SavedGame; using UnityEngine; using System.Collections.Generic; public class SavedGameBrowser : MonoBehaviour { public void ShowSaveGameUI() { ISavedGameClient savedGameClient = PlayGamesPlatform.Instance.SavedGame; savedGameClient.ShowSelectSavedGameUI( "Select a Save", 10, // maxDisplayedSavedGames true, // showCreateSaveUI true, // showDeleteSaveUI (status, game) => { if (status == SelectUIStatus.SavedGameSelected) { Debug.Log("User selected: " + game.Filename); Debug.Log("Description: " + game.Description); // Note: game is not open yet, you need to call Open... } else if (status == SelectUIStatus.UserClosedUI) { Debug.Log("User closed the UI without selecting"); } else { Debug.LogError("Error showing saved game UI: " + status); } }); } public void FetchAllSavedGames() { ISavedGameClient savedGameClient = PlayGamesPlatform.Instance.SavedGame; savedGameClient.FetchAllSavedGames( DataSource.ReadNetworkOnly, (status, savedGames) => { if (status == SavedGameRequestStatus.Success) { Debug.Log("Found " + savedGames.Count + " saved games:"); foreach (ISavedGameMetadata game in savedGames) { Debug.Log(" - " + game.Filename); Debug.Log(" Description: " + game.Description); Debug.Log(" Last Modified: " + game.LastModifiedTimestamp); Debug.Log(" Play Time: " + game.TotalTimePlayed); } } else { Debug.LogError("Failed to fetch saved games: " + status); } }); } public void DeleteSavedGame(ISavedGameMetadata gameToDelete) { ISavedGameClient savedGameClient = PlayGamesPlatform.Instance.SavedGame; savedGameClient.Delete(gameToDelete); Debug.Log("Deleted saved game: " + gameToDelete.Filename); } } ``` -------------------------------- ### Load and Save Game Data with Unity Source: https://context7.com/playgameservices/play-games-plugin-for-unity/llms.txt Use this C# script to manage saved game data. It includes methods for loading game progress from and saving game progress to the cloud using JSON serialization. Ensure the `ISavedGameClient` is properly initialized. ```csharp using GooglePlayGames; using GooglePlayGames.BasicApi; using GooglePlayGames.BasicApi.SavedGame; using UnityEngine; using System; using System.Text; [Serializable] public class GameProgress { public int level; public int score; public int coins; public string lastPlayed; } public class SaveLoadManager : MonoBehaviour { private ISavedGameMetadata currentSavedGame; private TimeSpan totalPlayTime = TimeSpan.Zero; public void LoadGameData() { if (currentSavedGame == null || !currentSavedGame.IsOpen) { Debug.LogError("No saved game is currently open!"); return; } ISavedGameClient savedGameClient = PlayGamesPlatform.Instance.SavedGame; savedGameClient.ReadBinaryData(currentSavedGame, (status, data) => { if (status == SavedGameRequestStatus.Success) { if (data != null && data.Length > 0) { string jsonData = Encoding.UTF8.GetString(data); GameProgress progress = JsonUtility.FromJson(jsonData); Debug.Log("Game data loaded!"); Debug.Log("Level: " + progress.level); Debug.Log("Score: " + progress.score); Debug.Log("Coins: " + progress.coins); ApplyProgressToGame(progress); } else { Debug.Log("No saved data found - starting new game"); } } else { Debug.LogError("Failed to read saved game data: " + status); } }); } public void SaveGameData(GameProgress progress) { if (currentSavedGame == null || !currentSavedGame.IsOpen) { Debug.LogError("No saved game is currently open!"); return; } progress.lastPlayed = DateTime.Now.ToString(); string jsonData = JsonUtility.ToJson(progress); byte[] dataToSave = Encoding.UTF8.GetBytes(jsonData); // Build metadata update SavedGameMetadataUpdate.Builder builder = new SavedGameMetadataUpdate.Builder(); builder = builder .WithUpdatedDescription("Level " + progress.level + " - " + progress.score + " pts") .WithUpdatedPlayedTime(totalPlayTime.Add(TimeSpan.FromMinutes(5))); ISavedGameClient savedGameClient = PlayGamesPlatform.Instance.SavedGame; savedGameClient.CommitUpdate( currentSavedGame, builder.Build(), dataToSave, (status, game) => { if (status == SavedGameRequestStatus.Success) { Debug.Log("Game saved successfully!"); currentSavedGame = null; // CommitUpdate closes the saved game } else { Debug.LogError("Failed to save game: " + status); } }); } private void ApplyProgressToGame(GameProgress progress) { // Apply loaded data to your game state } } ``` -------------------------------- ### Set Play Games Plugin Include Directories Source: https://github.com/playgameservices/play-games-plugin-for-unity/blob/master/SupportFiles/Public/PlayGamesPluginSupport/CMakeLists.txt Specifies the include directories for the Play Games plugin, pointing to the SDK's include folder. ```cmake target_include_directories(gpg PRIVATE ${GPG_SDK_PATH}/include ) ``` -------------------------------- ### Check Friends List Visibility and Load Friends (C#) Source: https://context7.com/playgameservices/play-games-plugin-for-unity/llms.txt Checks if the friends list is accessible and loads it if permissions are granted. Handles cases where permission is required or denied. ```csharp using GooglePlayGames; using GooglePlayGames.BasicApi; using UnityEngine; using UnityEngine.SocialPlatforms; public class FriendsManager : MonoBehaviour { public void CheckFriendsPermission() { PlayGamesPlatform.Instance.GetFriendsListVisibility( true, // forceReload status => { switch (status) { case FriendsListVisibilityStatus.Visible: Debug.Log("Friends list is accessible"); LoadFriends(); break; case FriendsListVisibilityStatus.RequestRequired: Debug.Log("Need to request friends permission"); RequestFriendsAccess(); break; case FriendsListVisibilityStatus.Unknown: Debug.Log("Friends visibility unknown"); break; case FriendsListVisibilityStatus.NotAuthorized: Debug.Log("Not authorized to access friends"); break; } }); } public void RequestFriendsAccess() { PlayGamesPlatform.Instance.AskForLoadFriendsResolution(status => { if (status == UIStatus.Valid) { Debug.Log("Friends permission granted!"); LoadFriends(); } else { Debug.Log("Friends permission denied or cancelled: " + status); } }); } public void LoadFriends() { // Load first page of friends (paginated) PlayGamesPlatform.Instance.LoadFriends( 10, // pageSize false, // forceReload status => { if (status == LoadFriendsStatus.LoadMore || status == LoadFriendsStatus.Completed) { IUserProfile[] friends = Social.localUser.friends; Debug.Log("Loaded " + friends.Length + " friends"); foreach (IUserProfile friend in friends) { Debug.Log("Friend: " + friend.userName + " (ID: " + friend.id + ")"); } } else { Debug.LogError("Failed to load friends: " + status); } }); } public void LoadMoreFriends() { PlayGamesPlatform.Instance.LoadMoreFriends(10, status => { Debug.Log("Load more friends status: " + status); Debug.Log("Total friends now: " + Social.localUser.friends.Length); }); } public void ShowFriendProfile(string friendId, string friendName) { PlayGamesPlatform.Instance.ShowCompareProfileWithAlternativeNameHintsUI( friendId, friendName, // otherPlayerInGameName Social.localUser.userName, // currentPlayerInGameName status => { Debug.Log("Profile UI closed with status: " + status); }); } } ``` -------------------------------- ### Platform Activation and Authentication Source: https://context7.com/playgameservices/play-games-plugin-for-unity/llms.txt This section covers the essential steps for activating the Google Play Games platform and authenticating the user. It includes methods for automatic sign-in attempts and manual sign-in initiation. ```APIDOC ## PlayGamesPlatform.Activate ### Description Activates the Google Play Games platform as the default social platform implementation. This must be called before using any Play Games features. ### Method `PlayGamesPlatform.Activate()` ### Endpoint N/A (This is a static method call within the Unity environment) ### Parameters None ### Request Example ```csharp using GooglePlayGames; using GooglePlayGames.BasicApi; using UnityEngine; public class GameManager : MonoBehaviour { void Start() { // Enable debug logging (optional) PlayGamesPlatform.DebugLogEnabled = true; // Activate Play Games Platform PlayGamesPlatform.Activate(); // Authenticate the user (automatic sign-in attempt) PlayGamesPlatform.Instance.Authenticate(OnSignInResult); } private void OnSignInResult(SignInStatus signInStatus) { if (signInStatus == SignInStatus.Success) { Debug.Log("Authenticated! Hello, " + Social.localUser.userName); Debug.Log("User ID: " + Social.localUser.id); } else { Debug.Log("Authentication failed: " + signInStatus); } } } ``` ### Response #### Success Response N/A (This method primarily affects the internal state of the plugin). #### Response Example N/A ``` ```APIDOC ## PlayGamesPlatform.ManuallyAuthenticate ### Description Manually requests sign-in with Play Games Services when the automatic sign-in attempt fails and your game requires access. ### Method `PlayGamesPlatform.Instance.ManuallyAuthenticate(System.Action callback)` ### Endpoint N/A (This is a method call on the PlayGamesPlatform instance) ### Parameters #### Callback - **callback** (System.Action) - Required - A callback function that will be invoked with the `SignInStatus` upon completion of the authentication attempt. ### Request Example ```csharp using GooglePlayGames; using GooglePlayGames.BasicApi; using UnityEngine; using UnityEngine.UI; public class LoginManager : MonoBehaviour { public Button signInButton; void Start() { PlayGamesPlatform.Activate(); // Try automatic authentication first PlayGamesPlatform.Instance.Authenticate(status => { if (status != SignInStatus.Success) { // Show manual sign-in button if automatic fails signInButton.gameObject.SetActive(true); } }); signInButton.onClick.AddListener(OnSignInButtonClicked); } void OnSignInButtonClicked() { PlayGamesPlatform.Instance.ManuallyAuthenticate(status => { if (status == SignInStatus.Success) { Debug.Log("Manual sign-in successful!"); signInButton.gameObject.SetActive(false); } else { Debug.Log("Manual sign-in failed: " + status); } }); } } ``` ### Response #### Success Response (200) N/A (Authentication status is provided via the callback) #### Response Example N/A ``` -------------------------------- ### Manually Authenticate User with Play Games Source: https://context7.com/playgameservices/play-games-plugin-for-unity/llms.txt Manually requests sign-in with Play Games Services if the automatic sign-in attempt fails. This is useful when your game requires user authentication to proceed. ```csharp using GooglePlayGames; using GooglePlayGames.BasicApi; using UnityEngine; using UnityEngine.UI; public class LoginManager : MonoBehaviour { public Button signInButton; void Start() { PlayGamesPlatform.Activate(); // Try automatic authentication first PlayGamesPlatform.Instance.Authenticate(status => { if (status != SignInStatus.Success) { // Show manual sign-in button if automatic fails signInButton.gameObject.SetActive(true); } }); signInButton.onClick.AddListener(OnSignInButtonClicked); } void OnSignInButtonClicked() { PlayGamesPlatform.Instance.ManuallyAuthenticate(status => { if (status == SignInStatus.Success) { Debug.Log("Manual sign-in successful!"); signInButton.gameObject.SetActive(false); } else { Debug.Log("Manual sign-in failed: " + status); } }); } } ``` -------------------------------- ### Load and Show Achievements UI Source: https://context7.com/playgameservices/play-games-plugin-for-unity/llms.txt Loads achievement data and displays the built-in achievements UI. The UI closure status is logged. ```csharp using GooglePlayGames; using GooglePlayGames.BasicApi; using UnityEngine; using UnityEngine.SocialPlatforms; public class AchievementBrowser : MonoBehaviour { public void ShowAchievementsUI() { // Show the standard Google Play Games achievements UI PlayGamesPlatform.Instance.ShowAchievementsUI(status => { Debug.Log("Achievements UI closed with status: " + status); }); } public void LoadAllAchievements() { Social.LoadAchievements(achievements => { Debug.Log("Loaded " + achievements.Length + " achievements"); foreach (IAchievement ach in achievements) { Debug.Log("Achievement: " + ach.id); Debug.Log(" Completed: " + ach.completed); Debug.Log(" Progress: " + ach.percentCompleted + "%" ); Debug.Log(" Last Reported: " + ach.lastReportedDate); } }); } public void LoadAchievementDescriptions() { Social.LoadAchievementDescriptions(descriptions => { Debug.Log("Loaded " + descriptions.Length + " achievement descriptions"); foreach (IAchievementDescription desc in descriptions) { Debug.Log("Achievement: " + desc.title); Debug.Log(" Description: " + desc.achievedDescription); Debug.Log(" Points: " + desc.points); Debug.Log(" Hidden: " + desc.hidden); } }); } } ``` -------------------------------- ### Open Saved Game with Automatic Conflict Resolution Source: https://context7.com/playgameservices/play-games-plugin-for-unity/llms.txt Opens a saved game file using automatic conflict resolution. It defaults to `ConflictResolutionStrategy.UseLongestPlaytime`. Ensure `PlayGamesPlatform.Instance.SavedGame` is initialized. ```csharp using GooglePlayGames; using GooglePlayGames.BasicApi; using GooglePlayGames.BasicApi.SavedGame; using UnityEngine; using System; public class CloudSaveManager : MonoBehaviour { private ISavedGameMetadata currentSavedGame; private const string SAVE_FILE_NAME = "player_progress"; public void OpenSavedGame() { ISavedGameClient savedGameClient = PlayGamesPlatform.Instance.SavedGame; savedGameClient.OpenWithAutomaticConflictResolution( SAVE_FILE_NAME, DataSource.ReadNetworkOnly, ConflictResolutionStrategy.UseLongestPlaytime, (status, game) => { if (status == SavedGameRequestStatus.Success) { Debug.Log("Saved game opened successfully!"); Debug.Log("Filename: " + game.Filename); Debug.Log("Description: " + game.Description); Debug.Log("Total Played Time: " + game.TotalTimePlayed); currentSavedGame = game; } else { Debug.LogError("Failed to open saved game: " + status); } }); } } ``` -------------------------------- ### Record In-Game Events with Unity Source: https://context7.com/playgameservices/play-games-plugin-for-unity/llms.txt Use the Events API to increment predefined events by a specific amount. Ensure the event IDs are correctly defined. ```csharp using GooglePlayGames; using GooglePlayGames.BasicApi; using GooglePlayGames.BasicApi.Events; using UnityEngine; using System.Collections.Generic; public class EventsManager : MonoBehaviour { private const string EVENT_MONSTERS_KILLED = "CgkI...CQAQ"; private const string EVENT_GOLD_EARNED = "CgkI...CQBA"; public void RecordMonsterKill() { // Increment event by 1 PlayGamesPlatform.Instance.Events.IncrementEvent(EVENT_MONSTERS_KILLED, 1); Debug.Log("Monster kill event recorded"); } public void RecordGoldEarned(uint amount) { // Increment event by custom amount PlayGamesPlatform.Instance.Events.IncrementEvent(EVENT_GOLD_EARNED, amount); Debug.Log("Gold earned event recorded: " + amount); } public void FetchAllEvents() { PlayGamesPlatform.Instance.Events.FetchAllEvents( DataSource.ReadNetworkOnly, (status, events) => { if (status == ResponseStatus.Success) { Debug.Log("Fetched " + events.Count + " events"); foreach (IEvent evt in events) { Debug.Log("Event: " + evt.Name); Debug.Log(" ID: " + evt.Id); Debug.Log(" Description: " + evt.Description); Debug.Log(" Current Count: " + evt.CurrentCount); } } else { Debug.LogError("Failed to fetch events: " + status); } }); } public void FetchSpecificEvent(string eventId) { PlayGamesPlatform.Instance.Events.FetchEvent( DataSource.ReadNetworkOnly, eventId, (status, evt) => { if (status == ResponseStatus.Success && evt != null) { Debug.Log("Event: " + evt.Name + " = " + evt.CurrentCount); } }); } } ``` -------------------------------- ### Submit Score to Original vs. Google Play Source: https://github.com/playgameservices/play-games-plugin-for-unity/blob/master/README.md Demonstrates how to submit achievements to both the original default social platform and Google Play simultaneously. This is useful when integrating with multiple social platforms. ```csharp // 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); ``` -------------------------------- ### Handle Discovered Endpoint Source: https://context7.com/playgameservices/play-games-plugin-for-unity/llms.txt Implements the OnEndpointFound callback from IDiscoveryListener to send a connection request to a newly discovered endpoint. ```csharp // IDiscoveryListener implementation public void OnEndpointFound(EndpointDetails discoveredEndpoint) { Debug.Log("Found endpoint: " + discoveredEndpoint.Name); // Send connection request nearbyClient.SendConnectionRequest( "MyPlayer", discoveredEndpoint.EndpointId, Encoding.UTF8.GetBytes("Hello!"), response => { if (response.ResponseStatus == ConnectionResponse.Status.Accepted) { Debug.Log("Connection accepted!"); connectedEndpoints.Add(discoveredEndpoint.EndpointId); } }, this); } ``` -------------------------------- ### GameInfo Class Definition Source: https://github.com/playgameservices/play-games-plugin-for-unity/blob/master/Assets/Public/GooglePlayGames/com.google.play.games/Editor/template-GameInfo.txt Defines constants for game IDs and methods to check if they are initialized. This class is automatically generated and should not be edited directly. ```csharp // // Copyright (C) 2015 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // #if UNITY_ANDROID namespace GooglePlayGames { /// /// This file is automatically generated DO NOT EDIT! /// /// These are the constants defined in the Play Games Console for Game Services /// Resources. /// /// /// File containing information about the game. This is automatically updated by running the /// platform-appropriate setup commands in the Unity editor (which does a simple search / replace /// on the IDs in the form "__ID__"). We can check whether any particular field has been updated /// by checking whether it still retains its initial value - we prevent the constants from being /// replaced in the aforementioned search/replace by stripping off the leading and trailing "__". /// public static class GameInfo { private const string UnescapedApplicationId = "APP_ID"; private const string UnescapedIosClientId = "IOS_CLIENTID"; private const string UnescapedWebClientId = "WEB_CLIENTID"; private const string UnescapedNearbyServiceId = "NEARBY_SERVICE_ID"; public const string ApplicationId = "__APP_ID__"; // Filled in automatically public const string IosClientId = "__IOS_CLIENTID__"; // Filled in automatically public const string WebClientId = "__WEB_CLIENTID__"; // Filled in automatically public const string NearbyConnectionServiceId = "__NEARBY_SERVICE_ID__"; public static bool ApplicationIdInitialized() { return !string.IsNullOrEmpty(ApplicationId) && !ApplicationId.Equals(ToEscapedToken(UnescapedApplicationId)); } public static bool IosClientIdInitialized() { return !string.IsNullOrEmpty(IosClientId) && !IosClientId.Equals(ToEscapedToken(UnescapedIosClientId)); } public static bool WebClientIdInitialized() { return !string.IsNullOrEmpty(WebClientId) && !WebClientId.Equals(ToEscapedToken(UnescapedWebClientId)); } public static bool NearbyConnectionsInitialized() { return !string.IsNullOrEmpty(NearbyConnectionServiceId) && !NearbyConnectionServiceId.Equals(ToEscapedToken(UnescapedNearbyServiceId)); } /// /// Returns an escaped token (i.e. one flanked with "__") for the passed token /// /// The escaped token. /// The Token private static string ToEscapedToken(string token) { return string.Format("___{0}__", token); } } } #endif ``` -------------------------------- ### Request Server-Side Access Code (Unity C#) Source: https://context7.com/playgameservices/play-games-plugin-for-unity/llms.txt Use this method to request an authorization code for server-side access. It can optionally force a refresh token. The callback receives the auth code or null on failure. ```csharp using GooglePlayGames; using GooglePlayGames.BasicApi; using UnityEngine; using UnityEngine.Networking; using System.Collections; using System.Collections.Generic; public class ServerAuthManager : MonoBehaviour { private string serverUrl = "https://your-game-server.com"; public void GetServerAuthCode() { // Request auth code without refresh token PlayGamesPlatform.Instance.RequestServerSideAccess( false, // forceRefreshToken authCode => { if (!string.IsNullOrEmpty(authCode)) { Debug.Log("Auth code received: " + authCode.Substring(0, 10) + "..."); StartCoroutine(SendAuthCodeToServer(authCode)); } else { Debug.LogError("Failed to get auth code"); } }); } public void GetServerAuthCodeWithRefreshToken() { // Request auth code with refresh token for persistent server access PlayGamesPlatform.Instance.RequestServerSideAccess( true, // forceRefreshToken authCode => { if (!string.IsNullOrEmpty(authCode)) { Debug.Log("Auth code with refresh token received"); StartCoroutine(SendAuthCodeToServer(authCode)); } }); } public void GetServerAuthCodeWithScopes() { // Request auth code with additional OAuth scopes var scopes = new List { AuthScope.OPEN_ID, AuthScope.PROFILE, AuthScope.EMAIL }; PlayGamesPlatform.Instance.RequestServerSideAccess( true, // forceRefreshToken scopes, response => { if (!string.IsNullOrEmpty(response.GetAuthCode())) { Debug.Log("Auth code received with scopes"); Debug.Log("Granted scopes: " + response.GetGrantedScopes().Count); foreach (var scope in response.GetGrantedScopes()) { Debug.Log(" - " + scope); } } }); } private IEnumerator SendAuthCodeToServer(string authCode) { WWWForm form = new WWWForm(); form.AddField("auth_code", authCode); form.AddField("player_id", PlayGamesPlatform.Instance.GetUserId()); using (UnityWebRequest www = UnityWebRequest.Post(serverUrl + "/verify", form)) { yield return www.SendWebRequest(); if (www.result == UnityWebRequest.Result.Success) { Debug.Log("Server verified player: " + www.downloadHandler.text); } else { Debug.LogError("Server verification failed: " + www.error); } } } } ``` -------------------------------- ### Display User Profile Information Source: https://context7.com/playgameservices/play-games-plugin-for-unity/llms.txt Retrieves and displays the authenticated user's display name, ID, and avatar. Ensure the user is authenticated before calling this method. Loads the avatar image asynchronously if a URL is available. ```csharp using GooglePlayGames; using UnityEngine; using UnityEngine.UI; public class UserProfileDisplay : MonoBehaviour { public Text userNameText; public Text userIdText; public RawImage avatarImage; void DisplayUserInfo() { if (!PlayGamesPlatform.Instance.IsAuthenticated()) { Debug.LogError("User is not authenticated!"); return; } // Get user information string displayName = PlayGamesPlatform.Instance.GetUserDisplayName(); string oderId = PlayGamesPlatform.Instance.GetUserId(); string avatarUrl = PlayGamesPlatform.Instance.GetUserImageUrl(); userNameText.text = "Welcome, " + displayName; userIdText.text = "ID: " + oderId; // Load avatar image if available if (!string.IsNullOrEmpty(avatarUrl)) { StartCoroutine(LoadAvatarImage(avatarUrl)); } } System.Collections.IEnumerator LoadAvatarImage(string url) { using (var www = UnityEngine.Networking.UnityWebRequestTexture.GetTexture(url)) { yield return www.SendWebRequest(); if (www.result == UnityEngine.Networking.UnityWebRequest.Result.Success) { avatarImage.texture = UnityEngine.Networking.DownloadHandlerTexture.GetContent(www); } } } } ``` -------------------------------- ### User Information Retrieval Source: https://context7.com/playgameservices/play-games-plugin-for-unity/llms.txt This section details how to retrieve basic information about the currently authenticated user, such as their display name, unique ID, and avatar image URL. ```APIDOC ## GetUserDisplayName, GetUserId, GetUserImageUrl ### Description Retrieves the authenticated user's profile information including display name, unique ID, and avatar URL. ### Method - `PlayGamesPlatform.Instance.GetUserDisplayName()` - `PlayGamesPlatform.Instance.GetUserId()` - `PlayGamesPlatform.Instance.GetUserImageUrl()` ### Endpoint N/A (These are method calls on the PlayGamesPlatform instance) ### Parameters None ### Request Example ```csharp using GooglePlayGames; using UnityEngine; using UnityEngine.UI; public class UserProfileDisplay : MonoBehaviour { public Text userNameText; public Text userIdText; public RawImage avatarImage; void DisplayUserInfo() { if (!PlayGamesPlatform.Instance.IsAuthenticated()) { Debug.LogError("User is not authenticated!"); return; } // Get user information string displayName = PlayGamesPlatform.Instance.GetUserDisplayName(); string oderId = PlayGamesPlatform.Instance.GetUserId(); string avatarUrl = PlayGamesPlatform.Instance.GetUserImageUrl(); userNameText.text = "Welcome, " + displayName; userIdText.text = "ID: " + oderId; // Load avatar image if available if (!string.IsNullOrEmpty(avatarUrl)) { StartCoroutine(LoadAvatarImage(avatarUrl)); } } System.Collections.IEnumerator LoadAvatarImage(string url) { using (var www = UnityEngine.Networking.UnityWebRequestTexture.GetTexture(url)) { yield return www.SendWebRequest(); if (www.result == UnityEngine.Networking.UnityWebRequest.Result.Success) { avatarImage.texture = UnityEngine.Networking.DownloadHandlerTexture.GetContent(www); } } } } ``` ### Response #### Success Response (200) - **displayName** (string) - The display name of the authenticated user. - **userId** (string) - The unique ID of the authenticated user. - **avatarUrl** (string) - The URL of the user's avatar image (can be null or empty if not available). #### Response Example ```json { "displayName": "Gamer123", "userId": "12345678901234567890", "avatarUrl": "https://lh3.googleusercontent.com/..." } ``` ``` -------------------------------- ### Stop All Nearby Connections Source: https://context7.com/playgameservices/play-games-plugin-for-unity/llms.txt Stops all ongoing connections and advertising/discovery when the component is destroyed. Ensures resources are released. ```csharp void OnDestroy() { nearbyClient?.StopAllConnections(); } ``` -------------------------------- ### Handle Incoming Messages Source: https://context7.com/playgameservices/play-games-plugin-for-unity/llms.txt Implements the OnMessageReceived callback from IMessageListener to process incoming data from remote endpoints. ```csharp // IMessageListener implementation public void OnMessageReceived(string remoteEndpointId, byte[] data, bool isReliableMessage) { string message = Encoding.UTF8.GetString(data); Debug.Log("Message from " + remoteEndpointId + ": " + message); } ``` -------------------------------- ### GetPlayerStats Source: https://context7.com/playgameservices/play-games-plugin-for-unity/llms.txt Retrieves player statistics including session counts and engagement metrics for the authenticated user. ```APIDOC ## GetPlayerStats ### Description Retrieves player statistics including session counts and engagement metrics for the authenticated user. ### Method GET (Implicit, via SDK call) ### Endpoint N/A (SDK Function) ### Parameters None ### Request Example ```csharp PlayGamesPlatform.Instance.GetPlayerStats((statusCode, stats) => { // Handle response }); ``` ### Response #### Success Response (200) - **stats** (PlayerStats) - An object containing player statistics. - **NumberOfSessions** (int) - The total number of sessions the player has had. - **DaysSinceLastPlayed** (int) - The number of days since the player last played. - **NumberOfPurchases** (int) - The total number of purchases made by the player. - **SessionPercentile** (double) - The player's session percentile. - **SpendPercentile** (double) - The player's spend percentile. #### Response Example ```json { "NumberOfSessions": 15, "DaysSinceLastPlayed": 2, "NumberOfPurchases": 3, "SessionPercentile": 0.75, "SpendPercentile": 0.60 } ``` ``` -------------------------------- ### Handle Lost Endpoint Source: https://context7.com/playgameservices/play-games-plugin-for-unity/llms.txt Implements the OnEndpointLost callback from IDiscoveryListener to log when a previously discovered endpoint is no longer available. ```csharp public void OnEndpointLost(string lostEndpointId) { Debug.Log("Lost endpoint: " + lostEndpointId); } ``` -------------------------------- ### Report Score to Leaderboard Source: https://context7.com/playgameservices/play-games-plugin-for-unity/llms.txt Reports a score to a specified leaderboard. Includes options for simple submission, submission with metadata, and using Unity's standard Social API. ```csharp using GooglePlayGames; using UnityEngine; public class LeaderboardManager : MonoBehaviour { private const string LEADERBOARD_HIGH_SCORES = "CgkI...BQAQ"; public void SubmitScore(long score) { // Simple score submission PlayGamesPlatform.Instance.ReportScore(score, LEADERBOARD_HIGH_SCORES, success => { if (success) { Debug.Log("Score " + score + " submitted successfully!"); } else { Debug.LogError("Failed to submit score."); } }); } public void SubmitScoreWithMetadata(long score, string playerClass) { // Submit score with additional metadata PlayGamesPlatform.Instance.ReportScore( score, LEADERBOARD_HIGH_SCORES, playerClass, // metadata string success => { Debug.Log("Score with metadata submitted: " + success); }); } // Alternative using Unity's Social interface public void SubmitUsingStandardAPI(long score) { Social.ReportScore(score, LEADERBOARD_HIGH_SCORES, success => { Debug.Log("Score reported via Social API: " + success); }); } } ``` -------------------------------- ### Handle Remote Endpoint Disconnection Source: https://context7.com/playgameservices/play-games-plugin-for-unity/llms.txt Implements the OnRemoteEndpointDisconnected callback from IMessageListener to manage disconnections. ```csharp public void OnRemoteEndpointDisconnected(string remoteEndpointId) { Debug.Log("Endpoint disconnected: " + remoteEndpointId); connectedEndpoints.Remove(remoteEndpointId); } ``` -------------------------------- ### Achievements API Source: https://context7.com/playgameservices/play-games-plugin-for-unity/llms.txt Manage achievements for the authenticated user, including unlocking, incrementing, and revealing. ```APIDOC ## POST /achievements/unlock ### Description Unlocks a standard (non-incremental) achievement for the authenticated user. ### Method POST ### Endpoint N/A (SDK Function) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **achievementId** (string) - Required - The unique identifier for the achievement. ### Request Example ```csharp PlayGamesPlatform.Instance.UnlockAchievement("ACHIEVEMENT_ID", success => { // Handle result }); ``` ### Response #### Success Response (200) - **success** (boolean) - True if the achievement was unlocked successfully, false otherwise. #### Response Example ```json { "success": true } ``` ``` ```APIDOC ## POST /achievements/increment ### Description Increments an incremental achievement by a specified number of steps. ### Method POST ### Endpoint N/A (SDK Function) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **achievementId** (string) - Required - The unique identifier for the achievement. - **steps** (integer) - Required - The number of steps to increment the achievement by. ### Request Example ```csharp PlayGamesPlatform.Instance.IncrementAchievement("ACHIEVEMENT_ID", 1, success => { // Handle result }); ``` ### Response #### Success Response (200) - **success** (boolean) - True if the achievement was incremented successfully, false otherwise. #### Response Example ```json { "success": true } ``` ``` ```APIDOC ## POST /achievements/reveal ### Description Reveals a hidden achievement to the player without unlocking it. ### Method POST ### Endpoint N/A (SDK Function) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **achievementId** (string) - Required - The unique identifier for the achievement. ### Request Example ```csharp PlayGamesPlatform.Instance.RevealAchievement("ACHIEVEMENT_ID", success => { // Handle result }); ``` ### Response #### Success Response (200) - **success** (boolean) - True if the achievement was revealed successfully, false otherwise. #### Response Example ```json { "success": true } ``` ``` -------------------------------- ### Send Reliable Message to Connected Endpoints Source: https://context7.com/playgameservices/play-games-plugin-for-unity/llms.txt Sends a reliable message to all currently connected endpoints. If no endpoints are connected, it logs a message. ```csharp public void SendMessageToAll(string message) { if (connectedEndpoints.Count == 0) { Debug.Log("No connected endpoints"); return; } byte[] payload = Encoding.UTF8.GetBytes(message); nearbyClient.SendReliable(connectedEndpoints, payload); Debug.Log("Sent message to " + connectedEndpoints.Count + " endpoints"); } ```