Google Play Games plugin for Unity - GitHub

文章推薦指數: 80 %
投票人數:10人

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 ... Skiptocontent {{message}} playgameservices / play-games-plugin-for-unity Public Notifications Star 3k Fork 894 GooglePlayGamespluginforUnity Viewlicense 3k stars 894 forks Star Notifications Code Issues 612 Pullrequests 10 Actions Projects 0 Security Insights More Code Issues Pullrequests Actions Projects Security Insights master Branches Tags Couldnotloadbranches Nothingtoshow Loading {{refName}} default Couldnotloadtags Nothingtoshow {{refName}} default Loading 16 branches 152 tags Code Loading Latestcommit aerialninja andCopybara-Service Updatedependencyversionnumber … 02f06dd Oct14,2021 Updatedependencyversionnumber PiperOrigin-RevId:403070843 Change-Id:I8e36516c8f1219818444e195cc551269558180e9 02f06dd Gitstats 92 commits Files Permalink Failedtoloadlatestcommitinformation. Type Name Latestcommitmessage Committime current-build v10.12release. Nov24,2020 git-hooks \nInternalsync\n Dec10,2019 old-builds \nInternalsync\n Dec10,2019 samples v10.12release. Nov18,2020 scripts RemoveMultiplayerAPI. Aug14,2020 source Updatedependencyversionnumber Oct14,2021 CHANGELOG.txt v10.12release. Nov24,2020 CONTRIBUTING.md Internalsync Jan6,2020 Dockerfile \nInternalsync\n Dec10,2019 LICENSE \nInternalsync\n Dec10,2019 NEARBY.md RemoveMultiplayerfromsamplegames. Aug5,2020 README.md Mergepullrequest#2902fromplaygameservices:Fix-a-typo Oct13,2020 Settings.StyleCop \nInternalsync\n Dec10,2019 UPGRADING.txt \nInternalsync\n Dec10,2019 Viewcode GooglePlayGamespluginforUnity Overview Upgrading ConfigureYourGame Copythegameresourcesfromtheconsole Pastethegameresourcesintothepluginsetupdialog SetupChecklist AddAchievementsandLeaderboards AddEvents LoadYourGameProject PluginInstallation AndroidSetup AdditionalinstructionsonbuildingforAndroidonWindows RuntheProject ISocialPlatformCompliance NearbyConnectionsConfiguration Configuration&InitializationPlayGameServices AddingadditionalScopes Signin Incrementalauthorization Friends Viewfriends LoadingfriendswiththeISocialframework LoadingfriendswithPlayGamesPlatform Determiningfriendslistvisibility Viewaplayerprofile PlayerStatistics Settingpopupgravity Revealing/UnlockinganAchievement IncrementinganAchievement PostingaScoretoaLeaderboard ShowingtheAchievementsUI ShowingtheLeaderboardUI AccessingLeaderboarddata UsingSocial.ILeaderboard UsingPlayGamesPlatform.LoadScores() Gettingplayernames RecordingEvents SavingGameStatetotheCloud DisplayingsavedgamesUI Openingasavedgame Writingasavedgame Readingasavedgame Deletingasavedgame Retrievingserverauthenticationcodes Gettinganotherserverauthcodeafterexchangingthefirstcode Retrievingplayer'semail Retrievingplayer'sIDToken VideoRecording GetVideoCaptureCapabilities LaunchtheVideoCaptureOverlay GettheCurrentVideoCaptureState SetupaListenerforLiveUpdatestotheCaptureState Signout Decreasingapksize PlayGamesServicesProguardconfiguration (Advanced)UsingthePluginWithoutOverridingtheDefaultSocialPlatform SpecialThanks README.md GooglePlayGamespluginforUnity Copyright(c)2014GoogleInc.Allrightsreserved. TheGooglePlayGamespluginforUnity®isanopen-sourceprojectwhosegoal istoprovideapluginthatallowsgamedeveloperstointegratewith theGooglePlayGamesAPIfromagamewritteninUnity®.However,thisprojectis notinanywayendorsedorsupervisedbyUnityTechnologies. Unity®isatrademarkofUnityTechnologies. iOSisatrademarkofApple,Inc. Overview TheGooglePlayGamespluginforUnityallowsyoutoaccesstheGooglePlayGames APIthroughUnity'ssocialinterface. Thepluginprovidessupportforthe followingfeaturesoftheGooglePlayGamesAPI: signin friends unlock/reveal/incrementachievement postscoretoleaderboard cloudsaveread/write showbuilt-inachievement/leaderboardsUI events videorecordingofgameplay nearbyconnections NOTICE:ThisversionofthepluginnolongersupportsiOS.GooglePlaygamesservicesforiOSisdeprecated, andisnotlikelytofunctionasexpected.DonotuseGooglePlaygames servicesforiOSinnewapps.Seethedeprecationannouncementblogpostformoredetails. Features: easyGUI-orientedprojectsetup(integratedintotheUnityGUI) noneedtooverride/customizetheplayerActivity noneedtooverride/customizeAndroidManifest.xml Systemrequirements: Unity®5orabove. TodeployonAndroid: AndroidSDK Androidv4.0orhigher GooglePlayServiceslibrary,version11.6orabove Upgrading Ifyouhavealreadyintegratedyourprojectwithapreviousversionofthe pluginandwishtoupgradetoanewversion,pleaserefertothe upgradeinstructions. ConfigureYourGame Tousetheplugin,youmustfirstconfigureyour gameinthe GooglePlayDeveloperConsole.FollowtheinstructionsoncreatingaclientID. Beparticularlycarefulwhenenteringyourpackagenameandyour certificatefingerprints,sincemistakesonthosescreenscanbedifficultto recoverfrom. Copythegameresourcesfromtheconsole Onceyouconfigureatleastoneresource(event,achievement,orleaderboard), copytheresourceconfigurationfromtheGooglePlayDeveloperConsole,andpasteit intothesetupconfigurationinUnity.TogettheresourcesgototheAchievements tab,thenclickon"Getresources"onthebottomofthelist. Thenclickthe"Androidsection". Selectallthecontentsoftheresourceswindow,andcopythemtotheclipboard. Pastethegameresourcesintothepluginsetupdialog BackinUnity,openthesetupdialogWindow>GooglePlayGames>Setup...>AndroidSetup Enterthedirectorytosaveconstants-Enterthefolderfortheconstantsfile. Constantsclassname-thisisthenameoftheC#classtocreate,includingnamespace. ResourcesDefinition-pastetheresourcedatafromthePlayGamesconsolehere. WebclientID-thisistheclientIDofthelinkedwebapp.Itisonlyneededif youhaveaweb-basedbackendforyourgameandneedaserverauthcodetobe exchangedforanaccesstokenbythebackendserver,orifyouneedanidtoken fortheplayertomakeother,non-game,APIcalls. Thesetupprocesswillconfigureyourgamewiththeclientidandgeneratea C#classthatcontainsconstantsforeachofyourresources. SetupChecklist Makesuretodothefollowingiftheyarerelevanttoyourgame: AddtesteremailaddressestothetestingsectionofyourgameonthePlayGamesConsole. TheSHA1fingerprintusedtocreatethelinkedAndroidappisfromthekeystore usedtosigntheUnityapplication. AddAchievementsandLeaderboards Add achievements and leaderboards toyourgameintheGooglePlayDeveloperConsole.Foreachachievementand leaderboardyouconfigure,makesuretonote thecorrespondingachievementIDorleaderboardID, asthosewillbeneededwhenmakingtheAPIcalls. AchievementandleaderboardIDsarealphanumericstrings(e.g."Cgkx9eiuwi8_AQ"). AddEvents Eventsallowyoutotrackuseractionsinyourgameandreportonthemwith Analytics. ReadmoreabouthowtoconfigureanduseEventson GameConcepts-Events LoadYourGameProject Next,loadyourgameprojectintotheUnityeditor. Ifyoudonothaveagameprojecttoworkwith,youcanusetheMinimalsample availableinthesamplesdirectory.Usingthatsamplewillallowyouto quicklytestyoursetupandmakesureyoucanaccesstheAPI. Ifyouwanttotestalargersampleafteryouarefamiliarwiththeplugin, trytheCubicPilotgame. Moreinformationaboutbuildingthesamplescanbefoundinthe samplesREADMEfile. PluginInstallation Todownloadtheplugin,clonethisGitrepositoryintoyourfilesystem(ordownloaditas aZIPfileandunpackit).Then,lookfortheunitypackagefilein thecurrent-builddirectory: current-build/GooglePlayGamesPluginForUnity-X.YY.ZZ.unitypackage Toinstalltheplugin,simplyopenyourgameprojectinUnityandimportthatfileinto yourproject'sassets,asyouwouldanyotherUnitypackage.Thisisaccomplishedthrough theAssets>ImportPackage>CustomPackagemenuitem(youcanalsoreachthismenuit byright-clickingtheAssetsfolder). Next,makesureyourcurrentbuildplatformissettoAndroid.From File>BuildSettings…selectAndroidandclickSwitchPlatform. YoushouldnowseeanewmenuitemwasaddedunderWindow>GooglePlayGames. Ifyoudon'tseethenewmenuitems,refreshtheassetsby clickingAssets>Refreshandtryagain. AndroidSetup Next,setupthepathtoyourAndroidSDKinstallationinUnity.Thisislocatedinthe preferencesmenu,undertheExternalToolssection. ToconfigureyourUnitygametorunwithGooglePlayGamesonAndroid,first opentheAndroidSDKmanagerandverifythatyouhavedownloadedthefollowing packages.DependingonifyouareusingtheSDKmanagerfromAndroidStudio, orusingthestandaloneSDKmanager,thenameofthecomponentsmaybedifferent. GooglePlayServices AndroidSupportLibrary LocalMavenrepositoryforSupportLibraries(AlsoknownasAndroidSupportRepository) GoogleRepository Android6.0(API23)(thisdoesnotaffecttheminSDKversion). Next,configureyourgame'spackagename.Todothis,clickFile>BuildSettings, selecttheAndroidplatformandclickPlayerSettingstoshowUnity's PlayerSettingswindow.Inthatwindow,lookfortheBundleIdentifiersetting underOtherSettings.Enteryourpackagenamethere(forexample com.example.my.awesome.game). InordertosignintoPlayGameServices,youneedtosignyourAPKfile, makesurethatyouaresigningitwiththe correctcertificate,thatis,theonethatcorrespondstotheSHA1certificate fingerprintyouenteredintheDeveloperConsoleduringthesetup. Next,clicktheWindow|GooglePlayGames|Setup-Androidsetupmenuitem. ThiswilldisplaytheAndroidsetupscreen. EntertheConstantsclassname.Thisisthenameofthefullyqualifiedclass thatwillbeupdated(orcreated)whichcontainstheIDsofthegameresources. Theformatofthenameis..Forexample,AwesomeGame.GPGSIds Pastetheresourcedefinitiondata.ThisistheXMLdatafromtheGooglePlayDeveloperConsole whichcontainstheresourceIDsaswellastheApplicationIDforAndroid. ThisdataisfoundintheGooglePlayDeveloperConsolebyclicking"Getresources"onanyofthe resourcepages(e.g.AchievementsorLeaderboards),thenclickingAndroid. Afterpastingthedataintothetextarea,clicktheSetupbutton. Note:Ifyouareusingawebapplicationorbackendserverwithyourgame, youcanlinkthewebapplicationtothegametoenablegettingtheplayer's idtokenand/oremailaddress.Todothis,linkawebapplicationtothe gameintheGooglePlayDeveloperConsole,andentertheclientidfor thewebapplicationintothesetupdialog. AdditionalinstructionsonbuildingforAndroidonWindows IfyouareusingWindows,youmustmakesurethatyourJavaSDKinstallation canbeaccessedbyUnity.Todothis: SettheJAVA_HOMEenvironmentvariabletoyourJavaSDKinstallationpath (forexample,C:\ProgramFiles\Java\jdk1.7.0_45). AddtheJavaSDK'sbinfoldertoyourPATHenvironmentvariable (forexample,C:\ProgramFiles\Java\jdk1.7.0_45\bin) Reboot. Howtoeditenvironmentvariables:InWindows2000/XP/Vista/7, right-clickMyComputer,thenProperties,thengotoAdvancedSystemProperties (orSystemPropertiesandthenclicktheAdvancedtab),then clickEnvironmentVariables.OnWindows8,pressWindowsKey+Wand searchforenvironmentvariables Formoreinformation,consultthedocumentationforyourversionofWindows. RuntheProject IfyouareworkingwiththeMinimalsample,youshouldbeabletobuild andruntheprojectatthispoint.YouwillseeascreenwithanAuthenticatebutton, andyoushouldbeabletosigninwhenyouclickit. TobuildandrunonAndroid,click File>BuildSettings,selecttheAndroidplatform,then SwitchtoPlatform,thenBuildandRun. ISocialPlatformCompliance TheGooglePlayGamespluginimplementsUnity's socialinterface, forcompatibilitywithgamesthatalreadyusethatinterfacewhenintegratingwithother platforms.However,somefeaturesareuniquetoPlayGamesandare offeredasextensionstothestandardsocialinterfaceprovidedbyUnity. ThestandardAPIcallscanbeaccessedthroughtheSocial.Activeobject, whichisareferencetoanISocialPlatforminterface.Thenon-standard GooglePlayGamesextensionscanbeaccessedbycastingtheSocial.Active objecttothePlayGamesPlatformclass,wheretheadditionalmethodsare available. NearbyConnectionsConfiguration Inordertousenearbyconnections,aserviceidwhichuniquelyidentifiesthe setofapplicationsthatcaninteractneedstobeconfigured. ThisisdonebyclickingtheWindow>GooglePlayGames>NearbyConnectionssetup... menuitem.Thiswilldisplaythe nearbyconnectionssetupscreen.OnthisscreenentertheserviceIDyouwanttouse. Itshouldbesomethingthatidentifiesyourapplication,andfollowsthe samerulesasthebundleid(forexample:com.example.myawesomegame.nearby). Onceyouentertheid,pressSetup. Tousenearbyconnections,theplayerdoesnotneedtobeauthenticated, andnoGooglePlayDeveloperConsoleconfigurationisneeded. Fordetailedinformationonnearbyconnectionusage, pleaserefertonearbyconnections. Configuration&InitializationPlayGameServices Inordertosavegameprogressorrequireaccesstoaplayer'sGoogle+social graph,thedefaultconfigurationneedstobereplacedwithacustom configuration.TodothisusethePlayGamesClientConfiguration. Ifyourgamedoesnotusethesefeatures,thenthereisnoneedto usingGooglePlayGames; usingGooglePlayGames.BasicApi; usingUnityEngine.SocialPlatforms; PlayGamesClientConfigurationconfig=newPlayGamesClientConfiguration.Builder() //enablessavinggameprogress. .EnableSavedGames() //requeststheemailaddressoftheplayerbeavailable. //Willbringupapromptforconsent. .RequestEmail() //requestsaserverauthcodebegeneratedsoitcanbepassedtoan //associatedbackendserverapplicationandexchangedforanOAuthtoken. .RequestServerAuthCode(false) //requestsanIDtokenbegenerated.ThisOAuthtokencanbeusedto //identifytheplayertootherservicessuchasFirebase. .RequestIdToken() .Build(); PlayGamesPlatform.InitializeInstance(config); //recommendedfordebugging: PlayGamesPlatform.DebugLogEnabled=true; //ActivatetheGooglePlayGamesplatform PlayGamesPlatform.Activate(); Afteractivated,youcanaccessthePlayGamesplatformthrough Social.Active.YoushouldonlycallPlayGamesPlatform.Activateoncein yourapplication.Makingthiscallwillnotdisplayanythingonthescreenand willnotinteractwiththeuserinanyway. AddingadditionalScopes Youcanaddadditionalscopestotheauthenticationprocessbycalling PlayGamesClientConfiguration.Builder().AddOauthScope(scope). Note:addingadditionalscopeswithmostlikelyrequireuserconsentwhen startingyourgame. Signin Tosignin,callPlayGamesPlatform.Instance.Authenticate,withaSignInInteractivityenum. UsingtheenumCanPromptOncefollowsthebestsign-inpracticesanditshouldbeusedwhenyourgamestarts.Itwill: Alwaysattempttosilentsign-in Ifsilentsign-infails,checkiftheuserhaspreviouslydeclinedtosignin. Iftheuserhasn’tpreviouslydeclinedtosignin,thenchecktheinternetconnectionandpromptinteractivesign-inifinternetisavailable Iftheinteractivesign-iniscancelledbytheuser,torememberthisasa‘decline’forthe2ndstepofthenextsign-inattempt. Additionally,youshouldputasign-in/sign-outbuttoncontrolforPlayGamessomewherethatmakessenseforyourgame,andwhereyouruserscaneasilyfindit.Forthisbutton,youshouldusetheenumCanPromptAlways. ThefulllistofenumsforPlayGamesPlatform.Instance.Authenticateare: CanPromptOncewillhelpusershaveaseamlesssign-inexperience,byautomaticallysigningtheminwhenyourgamestarts.Ifautomaticsign-inisnotsuccessful,theywillbepromptedtosigninmanuallywithaninteractivesign-inscreen.Iftheuserdoesnotsigninusingtheinteractivescreen,theywillnotbeaskedtosignininteractivelyagain.Usethiswhenyourgamestartsup. CanPromptAlwayswhenused,interactivesign-inwillbestarted,ifsilentsign-infailsandtheuserwillseealwaysseeUIs(thisdoesnotcountthenumberofdeclines).Usethisforyourin-gamePGSsign-inbutton. NoPromptwhenused,silentsign-inwillbeattemptedbutnoUIswillbeshowntotheuserifsilentsign-infails. usingGooglePlayGames; usingUnityEngine.SocialPlatforms; ... //authenticateuser: PlayGamesPlatform.Instance.Authenticate(SignInInteractivity.CanPromptOnce,(result)=>{ //handleresults }); Theresultcodeisanenum,whichgivesyoudifferentfailurereasonsthatwillhelpyouunderstandsign-infailuresbetter. Interactivesign-inwillshowtherequiredconsentdialogs.Iftheuserhasalready signedintothegameinthepast,thisprocesswillbesilentandtheuserwill nothavetointeractwithanydialogs. NotethatyoucannotmakeanygamesAPIcalls(unlockachievements,postscores, etc)untilyougetasuccessfulreturnvaluefromAuthenticate,soitis goodpracticetoputupastandbyscreenuntilthecallbackiscalled,tomake suretheusercan'tstartplayingthegameuntiltheauthenticationprocess completes. Incrementalauthorization Asopposedtoaskingallscopesyouneedinadvance,youcanstartwiththemostbasiconesandthenaskfornewscopeswhenyouneedthemasit’ssuggestedinthequalitychecklist.Thiswillallowsilentsign-intosucceed,becausesilentsign-inwillalwaysfailifyouaskformorethanGAMES_LITEand,ifyouuseSavedGames,DRIVE.APP_DATA.Askingforscopesatthetimeyouneedthemwillalsohelpusersunderstandwhyyouareaskingforascopeandmakethemmorelikelytogivepermissions. Tolearnifyoualreadyhaveapermissionforascopeandtoaskforanewone,youcanusethecodesnippetsbelow. PlayGamesPlatform.Instance.HasPermission("email") PlayGamesPlatform.Instance.RequestPermission("email",result=>{ //handleresults }); Friends PlayGamesFriendsallowsplayerstocreateandmaintainacross-gamesfriendslist.Youcanrequestaccesstothisfriendslisttohelpyourplayersplayyourgamewiththeirfriends.SeetheFriendsconceptpageformoredetailsonthefriendssystem. ToenableFriends,usethefollowingfunctions: Viewfriends:Requestaccesstoaplayer’sfriendslist,soyoucanaddtheirplaygamesfriendstoyourin-gamefriendslist Viewaplayerprofile:LetaplayerviewthePlayGamesprofileofanotherplayer.Thisisessentialsoaplayerknowswhotheirfriendsare,andcanconnecttootherPlayGamesplayersinyourgame.ThiswillneedtobetiedtoaUIelementtotriggerthepopup.Seethefriendsguidelinesfordetails. SeethebestpracticesguidelinesforinstructionsonhowbesttoimplementtheseAPIs. Note:TouseFriends,youneedtoupdateyourPGSSDKtoversion20.0.0 Viewfriends Therearetwowaystoloadfriends,eitherusingtheISocialframeworkordirectlywithPlayGamesPlatform. LoadingfriendswiththeISocialframework Social.localUser.LoadFriends((success)=>{ Debug.Log("FriendsloadedOK:"+ok)); foreach(IUserProfilepinSocial.localUser.friends){ Debug.Log(p.userName+"isafriend"); } However,thiscallwillfailifthecurrentplayerhasnotyetgrantedpermissiontothegametoaccessthisinformation.UseGetLastLoadFriendsStatustocheckifLoadFriendsfailedduetomissingconsent. PlayGamesPlatform.Instance.GetLastLoadFriendsStatus((status)=>{ //Checkforconsent if(status==LoadFriendsStatus.ResolutionRequired){ //Askforresolution. } }); AgamecanaskthecurrentplayertosharethefriendslistbycallingAskForLoadFriendsResolution. PlayGamesPlatform.Instance.AskForLoadFriendsResolution((result)=>{ if(result==UIStatus.Valid){ //Useragreedtosharefriendswiththegame.Reloadfriends. }else{ //Userdoesn’tagreetosharethefriendslist. } }); Thisfunctionwillshowtheappropriateplatform-specificfriendssharingUI.ThisUIaskstheplayeriftheywanttosharetheirfriendswiththegame. LoadingfriendswithPlayGamesPlatform AnotherwayofloadingfriendsistouseLoadFriendsandLoadMoreFriends: PlayGamesPlatform.Instance.LoadFriends(pageSize,forceReload,(status)=>{ //Checkifthecallissuccessfulandiftherearemorefriendstoload. }); PlayGamesPlatform.Instance.LoadMoreFriends(pageSize,(status)=>{ //Checkiftherearemorefriendstoload. }); ThepageSizeparamrepresentsthenumberofentriestorequestforthispage.Notethatifcacheddataalreadyexists,thereturnedbuffermaycontainmorethanthissize.Thebufferisguaranteedtocontainatleastthismanyentriesifthecollectioncontainsenoughrecords.IfforceReloadissettotrue,thiscallwillclearanylocally-cacheddataandattempttofetchthelatestdatafromtheserver.Thiswouldcommonlybeusedforactionslikeauser-initiatedrefresh.Normally,thisshouldbesettofalsetogaintheadvantagesofdatacaching. IfthecallbackreturnsLoadFriendsStatus.LoadMore,thentherearemorefriendstoload.LoadFriendsStatus.ResolutionRequiredsignalsthattheuserhasnotsharedthefriendslistandyoucandirectlycallPlayGamesPlatform.Instance.AskForLoadFriendsResolution. Determiningfriendslistvisibility UsePlayGamesPlatform.Instance.GetFriendsListVisibilitytocheckiftheuserhassharedthefriendslistwiththegame.Possiblereturnstatusesare: FriendsListVisibilityStatus.RequestRequiredindicatesyoumustaskforconsent. FriendsListVisibilityStatus.Visibleindicatesthatloadingthefriendslistshouldsucceed. FriendsListVisibilityStatus.Unknowngenerallyshouldn'thappen.YoucansetforceReloadtotruetorefreshthedata. PlayGamesPlatform.Instance.GetFriendsListVisibility(forceReload,(friendsListVisibilityStatus)=>{}); Viewaplayerprofile Toaddorremoveaplayerasafriend,usetheshowandcompareprofilefunction.ThisfunctiontriggersabottomsheetdialogshowingthePlayGamesprofileoftheuser;callthefunctionwiththeplayerIdoftherequestedplayer.Iftheplayerandfriendhavein-gamenicknames,usetheminthecalltoaddmorecontexttotheprofileUI: PlayGamesPlatform.Instance.ShowCompareProfileWithAlternativeNameHintsUI( mFirstFriendId,/*otherPlayerInGameName=*/null,/*currentPlayerInGameName=*/null, (result)=>{ //Profilecomparisonviewhasclosed. }); PlayerStatistics ThePlayerStatsAPIletyoutailorgameexperiencestospecificsegments ofplayersanddifferentstagesoftheplayerlifecycle.Youcanbuild tailoredexperiencesforeachplayersegmentbasedonhowplayersare progressing,spending,andengaging.Forexample,youcanusethisAPIto takeproactiveactionstoencouragealessactiveplayertore-engagewith yourgame,suchasbydisplayingandpromotingnewin-gameitemswhenthe playersignsin. Thecallbacktakestwoparameters: Theresultcodelessthanorequaltozeroissuccess. SeeCommonStatusCodesforallvalues. ThePlayerStatsobjectoftypeGooglePlayGames.PlayGamesLocalUser.PlayerStats FormoreinformationseePlayerStats. Theplayerstatsareavailableafterauthenticating: ((PlayGamesLocalUser)Social.localUser).GetStats((rc,stats)=> { //-1meanscachedstats,0issucceess //seeCommonStatusCodesforallvalues. if(rc<=0&&stats.HasDaysSinceLastPlayed()){ Debug.Log("Ithasbeen"+stats.DaysSinceLastPlayed+"days"); } }); Settingpopupgravity Youcansetthegravityusedbypopupswhenshowinggameserviceselements suchasachievementnotifications.ThedefaultisTOP.Thiscanonly besetafterauthentication.Forexample: Social.localUser.Authenticate((boolsuccess)=> { if(success) { ((GooglePlayGames.PlayGamesPlatform)Social.Active).SetGravityForPopups(Gravity.BOTTOM); } }); Revealing/UnlockinganAchievement Tounlockanachievement,usetheSocial.ReportProgressmethodwitha progressvalueof100.0f: usingGooglePlayGames; usingUnityEngine.SocialPlatforms; ... //unlockachievement(achievementID"Cfjewijawiu_QA") Social.ReportProgress("Cfjewijawiu_QA",100.0f,(boolsuccess)=>{ //handlesuccessorfailure }); Noticethataccordingtotheexpectedbehaviorof Social.ReportProgress, aprogressof0.0fmeansrevealingtheachievementandaprogressof100.0f meansunlockingtheachievement.Therefore,torevealanachievement(thatwas previouslyhidden)withoutunlockingit,simplycallSocial.ReportProgresswith aprogressof0.0f. IncrementinganAchievement Ifyourachievementisincremental,thePlayGamesimplementationof Social.ReportProgresswilltrytobehaveascloselyaspossibletothe expectedbehavioraccordingtoUnity'ssocialAPI,butmaynotbeexact.For thisreason,werecommendthatyoudonotuseSocial.ReportProgressfor incrementalachievements.Instead,usethe PlayGamesPlatform.IncrementAchievementmethod,whichisaPlayGames extension. usingGooglePlayGames; usingUnityEngine.SocialPlatforms; ... //incrementachievement(achievementID"Cfjewijawiu_QA")by5steps PlayGamesPlatform.Instance.IncrementAchievement( "Cfjewijawiu_QA",5,(boolsuccess)=>{ //handlesuccessorfailure }); PostingaScoretoaLeaderboard Topostascoretoaleaderboard,callSocial.ReportScore. usingGooglePlayGames; usingUnityEngine.SocialPlatforms; ... //postscore12345toleaderboardID"Cfji293fjsie_QA") Social.ReportScore(12345,"Cfji293fjsie_QA",(boolsuccess)=>{ //handlesuccessorfailure }); TopostascoreandincludeametadatatagusethePlayGameServicesinstance directly: usingGooglePlayGames; usingUnityEngine.SocialPlatforms; ... //postscore12345toleaderboardID"Cfji293fjsie_QA"andtag"FirstDaily") Social.ReportScore(12345,"Cfji293fjsie_QA","FirstDaily",(boolsuccess)=>{ //handlesuccessorfailure }); Notethattheplatformandtheserverwillautomaticallydiscardscoresthatare lowerthantheplayer'sexistinghighscore,soyoucansubmitscoresfreely withoutanycheckstotestwhetherornotthescoreisgreaterthantheplayer's existingscore. ShowingtheAchievementsUI Toshowthebuilt-inUIforallachievements,call Social.ShowAchievementsUI. usingGooglePlayGames; usingUnityEngine.SocialPlatforms; ... //showachievementsUI Social.ShowAchievementsUI(); ShowingtheLeaderboardUI Toshowthebuilt-inUIforallleaderboards,callSocial.ShowLeaderboardUI. usingGooglePlayGames; usingUnityEngine.SocialPlatforms; ... //showleaderboardUI Social.ShowLeaderboardUI(); Ifyouwishtoshowaparticularleaderboardinsteadofallleaderboards,you canpassaleaderboardIDtothemethod.This,however,isaPlayGames extension,sotheSocial.ActiveobjectneedstobecasttoaPlayGamesPlatform objectfirst: usingGooglePlayGames; usingUnityEngine.SocialPlatforms; ... //showleaderboardUI PlayGamesPlatform.Instance.ShowLeaderboardUI("Cfji293fjsie_QA"); AccessingLeaderboarddata Thereare2methodstoretrievingtheleaderboardscoredata. UsingSocial.ILeaderboard ThismethodusestheILeaderboardinterfacetodefinethescopeandfilters forgettingthedata.Thisapproachallowsyoutoconfigure: TheleaderboardId Thecollection(socialorpublic) Thetimeframe(daily,weekly,all-time) Therankpositiontostartretrievingscores. Thenumberofscores(thedefaultis25). Filterbyuserid. Ifthefromparameterisnon-positive,thentheresultsreturnedare player-centered,meaningthescoresaroundthecurrentplayer'sscoreare returned. ILeaderboardlb=PlayGamesPlatform.Instance.CreateLeaderboard(); lb.id="MY_LEADERBOARD_ID"; lb.LoadScores(ok=> { if(ok){ LoadUsersAndDisplay(lb); } else{ Debug.Log("Errorretrievingleaderboardi"); } }); UsingPlayGamesPlatform.LoadScores() ThismethodusesthePlayGamesPlatformdirectly.Thisapproachprovides additionalflexibilityandinformationwhenaccessingtheleaderboarddata. PlayGamesPlatform.Instance.LoadScores( GPGSIds.leaderboard_leaders_in_smoketesting, LeaderboardStart.PlayerCentered, 100, LeaderboardCollection.Public, LeaderboardTimeSpan.AllTime, (data)=> { mStatus="Leaderboarddatavalid:"+data.Valid; mStatus+="\napprox:"+data.ApproximateCount+"have"+data.Scores.Length; }); TheparametersforLoadScores()are: leaderboardId startposition(topscoresorplayercentered) rowcount leaderboardcollection(socialorpublic) timespan(daily,weekly,all-time) callbackacceptingaLeaderboardScoreDataobject. TheLeaderboardScoreDataclassisusedtoreturninformationbacktothe callerwhenloadingscores.Themembersare: 1.Id-theleaderboardid 2.Valid-trueifthereturneddataisvalid(thecallwassuccessful) 3.Status-theResponseStatusofthecall 4.ApproximateCount-theapproximatenumberofscoresintheleaderboard 5.Title-thetitleoftheleaderboard 6.PlayerScore-thescoreofthecurrentplayer 7.Scores-thelistofscores 8.PrevPageToken-atokenthatcanbeusedtocallLoadMoreScores()to getthepreviouspageofscores. 9.NextPageToken-atokenthatcanbeusedtocallLoadMoreScores()to getthenextpageofscores. voidGetNextPage(LeaderboardScoreDatadata) { PlayGamesPlatform.Instance.LoadMoreScores(data.NextPageToken,10, (results)=> { mStatus="Leaderboarddatavalid:"+data.Valid; mStatus+="\napprox:"+data.ApproximateCount+"have"+data.Scores.Length; }); } ThiscallmayfailwhentryingtoloadfriendswithResponseCode.ResolutionRequirediftheuserhasnotsharedtheirfriendslistwiththegame.Inthiscase,useAskForLoadFriendsResolutiontorequestaccess. Gettingplayernames EachscorehastheuserIdoftheplayerthatmadethescore.Youcanuse Social.LoadUsers()toloadtheplayerprofile.Rememberthatthecontents oftheplayerprofilearesubjecttoprivacysettingsoftheplayers. internalvoidLoadUsersAndDisplay(ILeaderboardlb) { //gettheuserids ListuserIds=newList(); foreach(IScorescoreinlb.scores){ userIds.Add(score.userID); } //loadtheprofilesanddisplay(orinthiscase,log) Social.LoadUsers(userIds.ToArray(),(users)=> { stringstatus="Leaderboardloading:"+lb.title+"count="+ lb.scores.Length; foreach(IScorescoreinlb.scores){ IUserProfileuser=FindUser(users,score.userID); status+="\n"+score.formattedValue+"by"+ (string)( (user!=null)?user.userName:"**unk_"+score.userID+"**"); } Debug.log(status); }); } RecordingEvents Incrementinganeventisverysimple,justcallthefollowingmethod: usingGooglePlayGames; ... //IncrementstheeventwithId"YOUR_EVENT_ID"by1 PlayGamesPlatform.Instance.Events.IncrementEvent("YOUR_EVENT_ID",1); Thiscallis"fireandforget",itwillhandlebatchingandexecutionforyouinthebackground. SavingGameStatetotheCloud FordetailsonsavedgamesconceptsandAPIspleaserefertothedocumentation. Toenablesupportforsavedgames,thepluginmustbeinitializedwithsavedgamesenabledbycalling PlayGamesPlatform.InitializeInstance: PlayGamesClientConfigurationconfig=newPlayGamesClientConfiguration.Builder() //enablessavinggameprogress. .EnableSavedGames() .Build(); PlayGamesPlatform.InitializeInstance(config); DisplayingsavedgamesUI ThestandardUIforselectingorcreatingasavedgameentryisdisplayedbycalling: voidShowSelectUI(){ uintmaxNumToDisplay=5; boolallowCreateNew=false; boolallowDelete=true; ISavedGameClientsavedGameClient=PlayGamesPlatform.Instance.SavedGame; savedGameClient.ShowSelectSavedGameUI("Selectsavedgame", maxNumToDisplay, allowCreateNew, allowDelete, OnSavedGameSelected); } publicvoidOnSavedGameSelected(SelectUIStatusstatus,ISavedGameMetadatagame){ if(status==SelectUIStatus.SavedGameSelected){ //handleselectedgamesave }else{ //handlecancelorerror } } Openingasavedgame Inordertoreadorwritedatatoasavedgame,thesavedgameneedstobeopened.Sincethesavedgamestateiscachedlocally onthedeviceandsavedtothecloud,itispossibletoencounterconflictsinthestateofthesaveddata.Aconflict happenswhenadeviceattemptstosavestatetothecloudbutthedatacurrentlyonthecloudwaswrittenbyadifferentdevice. Theseconflictsneedtoberesolvedwhenopeningthesavedgamedata.Thereare2openmethodsthathandleconflictresolution, thefirstOpenWithAutomaticConflictResolutionacceptsastandardresolutionstrategytypeandautomaticallyresolvestheconflicts. Theothermethod,OpenWithManualConflictResolutionacceptsacallbackmethodtoallowthemanualresolutionoftheconflict. SeeGooglePlayGames/BasicApi/SavedGame/ISavedGameClient.csformoredetailsonthesemethods. voidOpenSavedGame(stringfilename){ ISavedGameClientsavedGameClient=PlayGamesPlatform.Instance.SavedGame; savedGameClient.OpenWithAutomaticConflictResolution(filename,DataSource.ReadCacheOrNetwork, ConflictResolutionStrategy.UseLongestPlaytime,OnSavedGameOpened); } publicvoidOnSavedGameOpened(SavedGameRequestStatusstatus,ISavedGameMetadatagame){ if(status==SavedGameRequestStatus.Success){ //handlereadingorwritingofsavedgame. }else{ //handleerror } } Writingasavedgame Oncethesavedgamefileisopened,itcanbewrittentosavethegamestate.ThisisdonebycallingCommitUpdate. TherearefourparameterstoCommitUpdate: thesavedgamemetadatapassedtothecallbackpassedtooneoftheOpencalls. theupdatestomaketothemetadata. theactualbytearrayofdata acallbacktocallwhenthecommitiscomplete. voidSaveGame(ISavedGameMetadatagame,byte[]savedData,TimeSpantotalPlaytime){ ISavedGameClientsavedGameClient=PlayGamesPlatform.Instance.SavedGame; SavedGameMetadataUpdate.Builderbuilder=newSavedGameMetadataUpdate.Builder(); builder=builder .WithUpdatedPlayedTime(totalPlaytime) .WithUpdatedDescription("Savedgameat"+DateTime.Now()); if(savedImage!=null){ //ThisassumesthatsavedImageisaninstanceofTexture2D //andthatyouhavealreadycalledafunctionequivalentto //getScreenshot()tosetsavedImage //NOTE:seesampledefinitionofgetScreenshot()methodbelow byte[]pngData=savedImage.EncodeToPNG(); builder=builder.WithUpdatedPngCoverImage(pngData); } SavedGameMetadataUpdateupdatedMetadata=builder.Build(); savedGameClient.CommitUpdate(game,updatedMetadata,savedData,OnSavedGameWritten); } publicvoidOnSavedGameWritten(SavedGameRequestStatusstatus,ISavedGameMetadatagame){ if(status==SavedGameRequestStatus.Success){ //handlereadingorwritingofsavedgame. }else{ //handleerror } } publicTexture2DgetScreenshot(){ //Createa2Dtexturethatis1024x700pixelsfromwhichthePNGwillbe //extracted Texture2DscreenShot=newTexture2D(1024,700); //Takesthescreenshotfromtoplefthandcornerofscreenandmapstotop //lefthandcornerofscreenShottexture screenShot.ReadPixels( newRect(0,0,Screen.width,(Screen.width/1024)*700),0,0); returnscreenShot; } Readingasavedgame Oncethesavedgamefileisopened,itcanbereadtoloadthegamestate.ThisisdonebycallingReadBinaryData. voidLoadGameData(ISavedGameMetadatagame){ ISavedGameClientsavedGameClient=PlayGamesPlatform.Instance.SavedGame; savedGameClient.ReadBinaryData(game,OnSavedGameDataRead); } publicvoidOnSavedGameDataRead(SavedGameRequestStatusstatus,byte[]data){ if(status==SavedGameRequestStatus.Success){ //handleprocessingthebytearraydata }else{ //handleerror } } Deletingasavedgame Oncethesavedgamefileisopened,itcanbedeleted.ThisisdonebycallingDelete. voidDeleteGameData(stringfilename){ //Openthefiletogetthemetadata. ISavedGameClientsavedGameClient=PlayGamesPlatform.Instance.SavedGame; savedGameClient.OpenWithAutomaticConflictResolution(filename,DataSource.ReadCacheOrNetwork, ConflictResolutionStrategy.UseLongestPlaytime,DeleteSavedGame); } publicvoidDeleteSavedGame(SavedGameRequestStatusstatus,ISavedGameMetadatagame){ if(status==SavedGameRequestStatus.Success){ ISavedGameClientsavedGameClient=PlayGamesPlatform.Instance.SavedGame; savedGameClient.Delete(game); }else{ //handleerror } } Retrievingserverauthenticationcodes InordertoaccessGoogleAPIsonabackendwebserveronbehalfofthecurrent player,youneedtogetanauthenticationcodefromtheclientapplicationand passthistoyourwebserverapplication.Thiscodecanthenbeexchangedfor anaccesstokentomakecallstothevariousAPIs. Formoredetailsonthisflowsee:GoogleSign-InforWebsites. TogettheServerAuthcode: ConfigurethewebclientIdofthewebapplicationlinkedtoyourgameinthe PlayGameConsole. CallPlayGamesClientConfiguration.Builder.RequestServerAuthCode(false)when creatingtheconfiguration. CallPlayGamesPlatform.Instance.GetServerAuthCode()oncetheplayerisauthenticated. Passthiscodetoyourserverapplication. Gettinganotherserverauthcodeafterexchangingthefirstcode Ifyourbackendserverinteractionsrequiresyoutosendaserverauthcode morethanonceperauthenticatedsession,youcancall PlayGamesPlatform.Instance.GetAnotherServerAuthCode(Actioncallback) Thismethodrequirestheplayertobeareadyauthenticatedandcorrectlyconfiguredto requestserverauthcodesonthisclient.Thismethodisimplementedbycalling GoogleSign-insilentlywhichreturnsanewserverauthcodewhenalreadysignedin. Retrievingplayer'semail Inordertoaccesstheplayer'semailaddress: CallPlayGamesClientConfiguration.Builder.RequestEmail()whencreating theconfiguration. Accesstheemailproperty((PlayGamesLocalUser)Social.localUser).Email aftertheplayerisauthenticated. Note: Ifallthatisneededisapersistentuniqueidentifierfortheplayer,thenyou shouldusetheplayer'sid.ThisisauniqueIDspecifictothatplayerand isthesamevalueallthetime. //callthisfromUpdate() Debug.Log("Localuser'semailis"+ ((PlayGamesLocalUser)Social.localUser).Email); Retrievingplayer'sIDToken Togettheplayer'sOAuthIDtoken: CallPlayGamesClientConfiguration.Builder.RequestIdToken()whencreating theconfiguration. Accesstheidtokenproperty((PlayGamesLocalUser)Social.localUser).GetIdToken() aftertheplayerisauthenticated. Note: TheIDTokencanbeusedtoidentifytherealplayeridentity.Asaresult requestingtheIDTokenwillcauseaconsentscreentobepresentedtotheuser duringlogin. VideoRecording IfyouwishtointegratethePlayGamesvideocapturefunctionalityintoyourgame, youcanusethefollowingfeatures. GetVideoCaptureCapabilities Youcanaccessthevideocapturecapabilitiesofadevice,includingifthecamera,mic, orwritestoragecanbeused,aswellasthecapturemodes(saveasafileorlivestream) andqualitylevels(SD,HD,etc.). PlayGamesPlatform.Instance.Video.GetCaptureCapabilities( (status,capabilities)=>{ boolisSuccess=CommonTypesUtil.StatusIsSuccess(status); if(isSuccess){ if(capabilities.IsCameraSupported&&capabilities.IsMicSupported&& capabilities.IsWriteStorageSupported&& capabilities.SupportsCaptureMode(VideoCaptureMode.File)&& capabilities.SupportsQualityLevel(VideoQualityLevel.SD)){ Debug.Log("Allrequestedcapabilitiesarepresent."); }else{ Debug.Log("Notallrequestedcapabilitiesarepresent!"); } }else{ Debug.Log("Error:"+status.ToString()); } }); LaunchtheVideoCaptureOverlay Beforeactivatingthevideocaptureoverlay,besuretocheckthatitcanbelaunchedwith IsCaptureSupportedandIsCaptureAvailable. if(PlayGamesPlatform.Instance.Video.IsCaptureSupported()){ PlayGamesPlatform.Instance.Video.IsCaptureAvailable(VideoCaptureMode.File, (status,isAvailable)=>{ boolisSuccess=CommonTypesUtil.StatusIsSuccess(status); if(isSuccess){ if(isAvailable){ PlayGamesPlatform.Instance.Video.ShowCaptureOverlay(); }else{ Debug.Log("Videocaptureisunavailable.Istheoverlayalreadyopen?"); } }else{ Debug.Log("Error:"+status.ToString()); } }); } GettheCurrentVideoCaptureState Whenrequired,youcanaccessthecurrentstateofthevideocaptureoverlay, includingwhetherornotitisrecording,andwhatmodeandresolutionitisrecordingin. PlayGamesPlatform.Instance.Video.GetCaptureState( (status,state)=>{ boolisSuccess=CommonTypesUtil.StatusIsSuccess(status); if(isSuccess){ if(state.IsCapturing){ Debug.Log("Currentlycapturingto"+state.CaptureMode.ToString()+"in"+ state.QualityLevel.ToString()); }else{ Debug.Log("Notcurrentlycapturing."); } }else{ Debug.Log("Error:"+status.ToString()); } }); SetupaListenerforLiveUpdatestotheCaptureState Toreceiveanupdatewheneverthestatusofthevideocaptureoverlaychanges, useRegisterCaptureOverlayStateChangedListener. Onlyonelistenercanberegisteredatatime,subsequentcallswillreplacethepreviouslistener. ThelistenercanbeunregisteredwithUnregisterCaptureOverlayStateChangedListener. PlayGamesPlatform.Instance.Video.RegisterCaptureOverlayStateChangedListener(this); TheobjectpassedtoRegisterCaptureOverlayStateChangedListenermustimplement CaptureOverlayStateListenerfromGooglePlayGames.BasicApi.Video. TheOnCaptureOverlayStateChangedinthatobjectwillbecalledwhenthestatechanges. publicvoidOnCaptureOverlayStateChanged(VideoCaptureOverlayStateoverlayState) { Debug.Log("OverlayStateisnow"+overlayState.ToString()); } Signout Tosigntheuserout,usethePlayGamesPlatform.SignOutmethod. usingGooglePlayGames; usingUnityEngine.SocialPlatforms; //signout PlayGamesPlatform.Instance.SignOut(); Aftersigningout,nofurtherAPIcallscanbemadeuntiltheuserauthenticatesagain. Decreasingapksize ItispossibletodecreasethesizeofthePlayGamesServicesUnityPluginbyremovingcodeforthePlayGamesServicesfeaturesthatyourgamedoesn’tusebyusingProguard.ProguardwillremovethePlayGamesUnityplugincodeforfeaturesthatarenotusedinyourgame,soyourgameshipswithonlythecodethatisneededandminimizesthesizeimpactofusingPlayGamesServices. Additionally,itispossibletoreducethesizeoftheentireUnityprojectusingUnity’sManagedCodeStripping,whichwillcompressyourentireproject.ThiscanbeusedinconjunctionwithProguard. PlayGamesServicesProguardconfiguration GotoFile>BuildSettings>PlayerSettingsandclickPublishingSettingssection.ChooseProguardforMinify>Release.Then,enableUserProguardFile.Ifyouwanttheplugintobeproguardedfordebugapksaswell,youcanchooseProguardforMinify>Debug. CopythecontentoftheproguardconfigurationintoAssets/Plugins/Android/proguard-user.txt. (Advanced)UsingthePluginWithoutOverridingtheDefaultSocialPlatform WhenyoucallPlayGamesPlatform.Activate,GooglePlayGamesbecomesyourdefaultsocialplatformimplementation,whichmeansthatstaticcallstomethodsinSocialandSocial.ActivewillbecarriedoutbytheGooglePlayGamesplugin.Thisisthedesiredbehaviorformostgamesusingtheplugin. However,ifforsomereasonyouwishtokeepthedefaultimplementationaccessible(forexample,touseittosubmitachievementsandleaderboardstoadifferentsocialplatform),youcanusetheGooglePlayGamespluginwithoutoverridingthedefaultone.Todothis: DonotcallPlayGamesPlatform.Activate IfXyzisthenameofamethodyouwishtocallontheSocialclass,donotcallSocial.Xyz.Instead,callPlayGamesPlatform.Instance.Xyz DonotuseSocial.ActivewheninteractingwithGooglePlayGames.Instead,usePlayGamesPlatform.Instance. Thatway,youcanevensubmitscoresandachievementssimultaneouslytotwoormoresocialplatforms: //Submitachievementtooriginaldefaultsocialplatform Social.ReportProgress("MyAchievementIdHere",100.0f,callback); //SubmitachievementtoGooglePlay PlayGamesPlatform.Instance.ReportProgress("MyGooglePlayAchievementIdHere",100.0f,callback); SpecialThanks Thissectionlistspeoplewhohavecontributedtothisprojectbywritingcode,improvingdocumentationorfixingbugs. DgizusseforfiguringoutthatsettingJAVA_HOMEisnecessaryonWindows. antonlichtforfixingabugwiththeparametertypeofshowErrorDialogonthesupportlibrary. pR0PsforfixinganissuewhereOnAchievementsLoadedwasnotacceptinganOPERATION_DEFERREDresultcodeasasuccess. friikyeuforhelpingdebuganissuethatcausedAPIcallstobequeuedupratherthanexecutedevenwhenconnected. About GooglePlayGamespluginforUnity Resources Readme License Viewlicense Releases 15 v0.10.12 Latest Nov24,2020 +14releases Packages0 Nopackagespublished Contributors65 +54contributors Languages C# 88.5% Java 10.1% Other 1.4% Youcan’tperformthatactionatthistime. Yousignedinwithanothertaborwindow.Reloadtorefreshyoursession. Yousignedoutinanothertaborwindow.Reloadtorefreshyoursession.



請為這篇文章評分?