Trouble with Google Play Games: The name 'PlayGamesPlatform' does not exist in the current context

I’ve recently had trouble with Unity Cloud on a repo that has Google Play Games Service Unity plugin, version 0.9.34. The error, of course, is:

The script-in-question, though, compiles just fine on my computer, and not only that, the target this is running on has been building just fine until recently. The only configuration setting I’m aware of changing is the Unity version. What’s going on?

Here’s the SocialManager.cs:

using UnityEngine;
using UnityEngine.SocialPlatforms;
using System;
using System.Collections.Generic;

// Import other packages specific to device
#if GOOGLE_PLAY_GAMES
// importing Google Play Games here
using GooglePlayGames;
using GooglePlayGames.BasicApi;
#elif UNITY_IOS
using UnityEngine.SocialPlatforms.GameCenter;
#endif

namespace OmiyaGames
{
    ///-----------------------------------------------------------------------
    /// <copyright file="SocialManagerWrapperClasses.cs" company="Omiya Games">
    /// The MIT License (MIT)
    ///
    /// Copyright (c) 2014-2016 Omiya Games
    ///
    /// Permission is hereby granted, free of charge, to any person obtaining a copy
    /// of this software and associated documentation files (the "Software"), to deal
    /// in the Software without restriction, including without limitation the rights
    /// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    /// copies of the Software, and to permit persons to whom the Software is
    /// furnished to do so, subject to the following conditions:
    ///
    /// The above copyright notice and this permission notice shall be included in
    /// all copies or substantial portions of the Software.
    ///
    /// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    /// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    /// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    /// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    /// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    /// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    /// THE SOFTWARE.
    /// </copyright>
    /// <author>Taro Omiya</author>
    /// <date>4/14/2016</date>
    ///-----------------------------------------------------------------------
    /// <summary>
    /// Singleton file used to authenticate with various social platforms.
    /// It also provides a social platform agnostic interface to report to
    /// leaderboards and achievements.
    /// <code>Singleton</code>'s events.
    /// </summary>
    /// <seealso cref="UnityEngine.SocialPlatforms"/>
    public class SocialManager : ISingletonScript
    {
        public enum LogInState
        {
            NotConnected,
            MiddleOfAuthenticating,
            AuthenticationSuccess
        }

        public enum ServiceType
        {
            None = -1,
            AppleGameCenter = 0,
            GooglePlayGames,
            AmazonGameCircle,
            //XboxLive,
            //Newgrounds,
            //GameJolt,
            //Kongregate,
            NumberOfServiceTypes
        }

#if UNITY_EDITOR
        class DebugSequence
        {
            uint index = 0;
            readonly float[] secondsSequence = new float[] { 15f, 0.1f, 0.2f };
            readonly bool[] successSequence = new bool[] { true, true, false };

            public void Next()
            {
                ++index;
            }

            public float WaitForSeconds
            {
                get
                {
                    return secondsSequence[index % secondsSequence.Length];
                }
            }

            public bool ReportedSuccess
            {
                get
                {
                    return successSequence[index % successSequence.Length];
                }
            }
        }

        readonly DebugSequence sequence = new DebugSequence();
#endif

        [SerializeField]
        bool authenticateOnStartUp = true;
        [SerializeField]
        bool showAchievementBannerOnStartUp = true;
        [SerializeField]
        int numberOfAuthenticationRetries = 3;

        [Header("Leaderboard IDs")]
        [Tooltip("The first leaderboard listed will be considered the default leaderboard to report to.")]
        [SerializeField]
        ServiceSpecificIds[] leaderboardIds;

        [Header("Achievement IDs")]
        [SerializeField]
        ServiceSpecificIds[] achievementIds;

        readonly Dictionary<LeaderboardKey, ILeaderboardWrapper> allLeaderboards = new Dictionary<LeaderboardKey, ILeaderboardWrapper>();
        readonly Dictionary<string, ServiceSpecificIds> leaderboardIdsMap = new Dictionary<string, ServiceSpecificIds>();
        readonly Dictionary<string, ServiceSpecificIds> achievementIdsMap = new Dictionary<string, ServiceSpecificIds>();
        readonly System.Text.StringBuilder warningBuilder = new System.Text.StringBuilder();
        LogInState authenticationState = LogInState.NotConnected;
        Action<float> onUpdate = null;
        Action<bool> onAchievementReported = null, onLeaderboardReported = null;

        #region Properties
        public LogInState CurrentLogInState
        {
            get
            {
                LogInState returnState = authenticationState;
                if (authenticationState == LogInState.AuthenticationSuccess)
                {
                    if (Social.localUser.authenticated == true)
                    {
                        returnState = LogInState.AuthenticationSuccess;
                    }
                    else
                    {
                        returnState = LogInState.NotConnected;
                    }
                }
                return returnState;
            }
            private set
            {
                authenticationState = value;
            }
        }

        public ServiceSpecificIds DefaultLeaderboardIds
        {
            get
            {
                ServiceSpecificIds returnId = null;
                if (leaderboardIds.Length > 0)
                {
                    returnId = leaderboardIds[0];
                }
                return returnId;
            }
        }

        public static bool IsSupported
        {
            get
            {
                return (CurrentService != ServiceType.None);
            }
        }

        public static ServiceType CurrentService
        {
            get
            {
                // TODO: as more services are implemented in SetupPlatformSpecificServices(),
                // add more supported services below here
#if (UNITY_EDITOR || DEMO)
                // In the editor or demo, don't allow any leaderboard services
                return ServiceType.None;
#elif GOOGLE_PLAY_GAMES
                return ServiceType.GooglePlayGames;
#elif UNITY_IOS
                return ServiceType.AppleGameCenter;
#else
                return ServiceType.None;
#endif
            }
        }

        static void SetupPlatformSpecificServices()
        {
            // Check if we need to do anything special based on platform
#if GOOGLE_PLAY_GAMES
            // Activate the Google Play Games platform
            PlayGamesPlatform.DebugLogEnabled = Debug.isDebugBuild;
            PlayGamesPlatform.Activate();
#endif
        }
        #endregion

        public bool LogInAsync(bool forceLogin = false)
        {
            bool returnIsAttemptingAuthentication = false;

            if ((IsSupported == true) && ((CurrentLogInState == LogInState.NotConnected) || (forceLogin == true)))
            {
                // Setup any platform specific quirks
                SetupPlatformSpecificServices();

                // Check if this manager supports this specific platform
                CurrentLogInState = LogInState.NotConnected;

                // Setup all flags
                returnIsAttemptingAuthentication = true;
                CurrentLogInState = LogInState.MiddleOfAuthenticating;

                // Start authentication process
                if (Debug.isDebugBuild == true)
                {
                    Debug.Log("Starting authentication!");
                }
                Social.localUser.Authenticate(OnAuthenticationComplete);
            }
            return returnIsAttemptingAuthentication;
        }

        public ServiceSpecificIds GetLeaderboardIds(string key)
        {
            return GetIds(key, leaderboardIdsMap, leaderboardIds);
        }

        public ServiceSpecificIds GetAchievementIds(string key)
        {
            return GetIds(key, achievementIdsMap, achievementIds);
        }

        public bool ReportAchievementProgressAsync(double record, string achievementKey, Action<bool> onResultsReceived = null)
        {
            bool returnIsAttemptingReport = false;
            ServiceSpecificIds requestedAchievementIds = null;

            // Clamp record
            if (record < 0)
            {
                record = 0;
            }
            else if (record > 100)
            {
                record = 100;
            }

            // Grab an achievement
            if (string.IsNullOrEmpty(achievementKey) == false)
            {
                requestedAchievementIds = GetAchievementIds(achievementKey);
            }

            // Make sure all the parameters are correct
            if (IsArgumentValid<double>("Achievement", requestedAchievementIds, achievementKey, record, onResultsReceived) == true)
            {
                // Grab the action to report to
                if (onResultsReceived == null)
                {
                    if (onAchievementReported == null)
                    {
                        onAchievementReported = new Action<bool>(OnAchievementReported);
                    }
                    onResultsReceived = onAchievementReported;
                }

                // Report score
                Social.ReportProgress(requestedAchievementIds.Id, record, onResultsReceived);

                // Indicate attempt succeeded
                returnIsAttemptingReport = true;

                // Show debugging messages
                if (Debug.isDebugBuild == true)
                {
                    lock (warningBuilder)
                    {
                        warningBuilder.Length = 0;
                        warningBuilder.Append("Reporting Achievement with key ");
                        warningBuilder.Append(achievementKey);
                        warningBuilder.Append(" and progress ");
                        warningBuilder.Append(record);
                        Debug.Log(warningBuilder.ToString());
                    }
                }
            }
            return returnIsAttemptingReport;
        }

        public bool RevealHiddenAchievementAsync(string achievementKey, Action<bool> onResultsReceived = null)
        {
            return ReportAchievementProgressAsync(0, achievementKey, onResultsReceived);
        }

        public bool UnlockAchievementAsync(string achievementKey, Action<bool> onResultsReceived = null)
        {
            return ReportAchievementProgressAsync(100, achievementKey, onResultsReceived);
        }

        public bool ReportLeaderboardRecordAsync(long record, string leaderboardKey = null, Action<bool> onResultsReceived = null)
        {
            bool returnIsAttemptingReport = false;
            ServiceSpecificIds requestedLeaderboardIds = DefaultLeaderboardIds;
            if (string.IsNullOrEmpty(leaderboardKey) == false)
            {
                requestedLeaderboardIds = GetLeaderboardIds(leaderboardKey);
            }

            // Make sure all the parameters are correct
            if (IsArgumentValid<long>("Leaderboard", requestedLeaderboardIds, leaderboardKey, record, onResultsReceived) == true)
            {
                // Grab the action to report to
                if (onResultsReceived == null)
                {
                    if (onLeaderboardReported == null)
                    {
                        onLeaderboardReported = new Action<bool>(OnLeaderboardReported);
                    }
                    onResultsReceived = onLeaderboardReported;
                }

                // Report score
                Social.ReportScore(record, requestedLeaderboardIds.Id, onResultsReceived);

                // Indicate attempt succeeded
                returnIsAttemptingReport = true;

                // Show debugging messages
                if (Debug.isDebugBuild == true)
                {
                    lock (warningBuilder)
                    {
                        warningBuilder.Length = 0;
                        warningBuilder.Append("Reporting Leaderboard with key ");
                        warningBuilder.Append(leaderboardKey);
                        warningBuilder.Append(" and score ");
                        warningBuilder.Append(record);
                        Debug.Log(warningBuilder.ToString());
                    }
                }
            }
            return returnIsAttemptingReport;
        }

        public ILeaderboardWrapper GetLeaderboard(string leaderboardKey = null,
            UserScope? userScope = null, TimeScope timeScope = TimeScope.AllTime,
            ushort startingRank = 0, ushort numberOfRanks = 0, bool retrieveScore = true)
        {
            ILeaderboardWrapper returnWrapper = null;
            ServiceSpecificIds leaderboardIds = DefaultLeaderboardIds;
            if (string.IsNullOrEmpty(leaderboardKey) == false)
            {
                leaderboardIds = GetLeaderboardIds(leaderboardKey);
            }

            // Check if the user scope is provided
            if (userScope.HasValue == false)
            {
                // If not, replace this parameter with default leaderboard ID
                userScope = Singleton.Get<GameSettings>().LeaderboardUserScope;
            }

            // Check if the ID is provided
            if (leaderboardIds == null)
            {
                if (Debug.isDebugBuild == true)
                {
                    Debug.LogWarning("No Leaderboard with key " + leaderboardKey + " found");
                }
            }
            else if (string.IsNullOrEmpty(leaderboardIds.Id) == true)
            {
                if (Debug.isDebugBuild == true)
                {
                    Debug.LogWarning("No Leaderboard ID provided");
                }
            }
            else
            {
                // Find a LeaderboardWrapper from the dictionary
                LeaderboardKey key = new LeaderboardKey(leaderboardIds.Id, userScope.Value, timeScope, startingRank, numberOfRanks);
                if (allLeaderboards.TryGetValue(key, out returnWrapper) == false)
                {
                    // Create a new wrapper, and add it to the dictionary
                    returnWrapper = new LeaderboardWrapper(key);
                    allLeaderboards.Add(key, returnWrapper);

                    // Check if we should retrive scores for this leaderboard
                    if ((retrieveScore == true) && (CurrentLogInState == LogInState.AuthenticationSuccess))
                    {
                        returnWrapper.LoadLeaderboardAsync();
                    }
                }
            }
            return returnWrapper;
        }

        #region Singleton Overrides
        public override void SingletonAwake(Singleton instance)
        {
            // Setup flag
            CurrentLogInState = LogInState.NotConnected;

            // Setup Banner
            SetupAchievementBanner(showAchievementBannerOnStartUp);

            // If this script is enabled, start authentication
            if ((authenticateOnStartUp == true) && (IsSupported == true))
            {
                // Sign to Singleton's update function
                OnDestroy();
                onUpdate = new System.Action<float>(OnEveryFrame);
                instance.OnUpdate += onUpdate;
            }
        }

        public override void SceneAwake(Singleton instance)
        {
        }
        #endregion

        #region Event Listeners
        void OnDestroy()
        {
            if (onUpdate != null)
            {
                Singleton.Instance.OnUpdate -= onUpdate;
                onUpdate = null;
            }
        }

        void OnEveryFrame(float deltaTime)
        {
            if (CurrentLogInState == LogInState.NotConnected)
            {
                if (numberOfAuthenticationRetries > 0)
                {
                    // Login
                    LogInAsync(true);

                    // Decrement the number of attempts to authenticate
                    --numberOfAuthenticationRetries;
                }
                else
                {
                    // We've went through all the retries
                    // Stop attempting to authenticate
                    OnDestroy();
                }
            }
        }

        // This function gets called when Authenticate completes
        // Note that if the operation is successful, Social.localUser will contain data from the server.
        void OnAuthenticationComplete(bool success)
        {
            // Check if authentication succeeded
            if (success == true)
            {
                // Stop attempting to authenticate
                if (authenticateOnStartUp == true)
                {
                    OnDestroy();
                }

                // Indicate success
                CurrentLogInState = LogInState.AuthenticationSuccess;
                if (Debug.isDebugBuild == true)
                {
                    Debug.Log("Authentication success!");
                }
            }
            else
            {
                // Indicate failure
                CurrentLogInState = LogInState.NotConnected;
                if (Debug.isDebugBuild == true)
                {
                    Debug.Log("Failed to authenticate");
                }
            }
        }

        void OnLeaderboardReported(bool success)
        {
            // Check if report succeeded
            if (Debug.isDebugBuild == true)
            {
                if (success == true)
                {
                    Debug.Log("Successfully recorded to a leaderboard!");
                }
                else
                {
                    Debug.Log("Failed to record to a leaderboard...");
                }
            }
        }

        void OnAchievementReported(bool success)
        {
            // Check if report succeeded
            if (Debug.isDebugBuild == true)
            {
                if (success == true)
                {
                    Debug.Log("Successfully recorded to an achivement!");
                }
                else
                {
                    Debug.Log("Failed to record to an achievement...");
                }
            }
        }
        #endregion

        #region Helpers
        static void SetupAchievementBanner(bool isVisible)
        {
#if !UNITY_EDITOR && UNITY_IOS
            GameCenterPlatform.ShowDefaultAchievementCompletionBanner(isVisible);
#endif
        }

        ServiceSpecificIds GetIds(string key, Dictionary<string, ServiceSpecificIds> dictionary, ServiceSpecificIds[] list)
        {
            ServiceSpecificIds returnId = null;

            // First, check if the leaderboard dictionary needs to be populated
            if (dictionary.Count != list.Length)
            {
                dictionary.Clear();
                for (int index = 0; index < list.Length; ++index)
                {
                    dictionary.Add(list[index].Key, list[index]);
                }
            }

            // Next, see if we can grab a leaderboard
            if (dictionary.TryGetValue(key, out returnId) == false)
            {
                returnId = null;
            }
            return returnId;
        }

        bool IsArgumentValid<T>(string type, ServiceSpecificIds ids, string achievementKey, T record, Action<bool> debug)
        {
            bool returnFlag = true;

#if UNITY_EDITOR
            // Return false
            returnFlag = false;

            // Pretend to run the results, anyway
            StartCoroutine(DebugUnsupportedPlatforms<T>(achievementKey, record, debug));
#else
            if (ids == null)
            {
                // Return false
                returnFlag = false;

                // Generate warning
                lock(warningBuilder)
                {
                    warningBuilder.Length = 0;
                    warningBuilder.Append("No ");
                    warningBuilder.Append(type);
                    warningBuilder.Append(" with key ");
                    warningBuilder.Append(achievementKey);
                    warningBuilder.Append("found!");
                    Debug.LogWarning(warningBuilder.ToString());
                }
            }
            else if (string.IsNullOrEmpty(ids.Id) == true)
            {
                // Return false
                returnFlag = false;

                // Generate warning
                lock (warningBuilder)
                {
                    warningBuilder.Length = 0;
                    warningBuilder.Append("No ");
                    warningBuilder.Append(type);
                    warningBuilder.Append(" ID provided");
                    Debug.LogWarning(warningBuilder.ToString());
                }
            }
            else if (CurrentLogInState != LogInState.AuthenticationSuccess)
            {
                // Return false
                returnFlag = false;

                // Generate warning
                Debug.LogWarning("User is not authenticated yet");
            }
#endif
            return returnFlag;
        }

#if UNITY_EDITOR
        System.Collections.IEnumerator DebugUnsupportedPlatforms<T>(string key, T record, Action<bool> debug)
        {
            sequence.Next();
            float seconds = sequence.WaitForSeconds;
            bool reportSuccess = sequence.ReportedSuccess;

            // Wait
            yield return new WaitForSeconds(seconds);

            // Print info
            if (Debug.isDebugBuild == true)
            {
                lock (warningBuilder)
                {
                    warningBuilder.Length = 0;
                    warningBuilder.Append("Waited ");
                    warningBuilder.Append(seconds);
                    warningBuilder.Append(" seconds, pretending to report to ");
                    warningBuilder.Append(key);
                    warningBuilder.Append(" with record ");
                    warningBuilder.Append(record);
                    warningBuilder.Append(" and success ");
                    warningBuilder.Append(reportSuccess);
                    Debug.Log(warningBuilder.ToString());
                }
            }
            if (debug != null)
            {
                debug(reportSuccess);
            }
        }
#endif
        #endregion
    }
}

And here’s the target configuration:

I’ve also attached the full log of the build and a few other scripts that might be relevant to SocialManager.cs. As far as I can tell, they have no compilation errors.

2829564–206137–text.txt (461 KB)
2829564–206138–SocialManager.cs (22.9 KB)
2829564–206139–ISingletonScript.cs (2.42 KB)
2829564–206140–SocialWrappers.cs (13.9 KB)

Can you try building with a different version of 5.4.x? I don’t see UNITY_ANDROID in the list of defines that were printed out by Unity at compile time which makes me think maybe there is a problem with our install of 5.4.2f1.

Yeah, I’ll try Unity 5.4.1f1 and see what happens. Thanks for checking!

Looks like it worked! Strange to see an installation problem like this…

Thanks for following up! Indeed that is strange to see. Will follow up and look into what happened with that install.

It looks like 5.4.2f1 was originally pulled from the main Unity download page because of installer issues. Unfortunately our build systems had already installed it at that point. We’ve replaced it with the recently released 5.4.2f2 so you shouldn’t see issues building with that version (but please let me know if you do).

Sorry for hijacking this thread, but I’m having the same issues with 5.4.2f2. The weird thing is, I can still build the game fine, and on my desktop computer there is no problem. On my laptop, I get the error ‘The name PlayGamesPlatform’ does not exist in the current context. The error only shows up in MonoDevelop. Any ideas?

Dear Danny,

I had the same problem in Unity 5.2.2f2 and it still remains after upgrading to 5.5.0f3.

What I also figured out is that:

PlayGamesPlatform.DebugLogEnabled = true;

In my case needs to be replaced with:

GooglePlayGames.OurUtils.Logger.DebugLogEnabled = true;

In order to work.

Is there maybe a change in the APIs or the standard install procedure is somehow not applicable…?

Can you help me with this issue?

Thank you in advance,
Thomas