赞
踩
接入API网上很多,这里放几个链接,大家参考,本文只讲我遇到的坑点
视频讲解登陆接入(里面有登入Unity账号的部分,没有需要的可以略着看)
一、GooglePlayGames插件导入
正常来说,导入GooglePlayGames插件后,不需要额外操作,但可能还是会打包失败,报错:找不到GooglePlayGames库
可以尝试以下操作
1.找到文件Assets/GooglePlayGames/com.google.play.games/GooglePlayGamesPluginDependencies.xml
把文件中
<repository>Packages/com.google.play.games/Editor/m2repository</repository>
修改为
<repository>Assets/GooglePlayGames/com.google.play.games/Editor/m2repository</repository>
2.执行:Assets->External Dependency Manager->Android Resolver->Force Resolve
查看GeneratedLocalRepo目录中是否有GooglePlayGames目录
如果以上两步操作都没有问题,打包时还是提示找不到GooglePlayGames库,可以尝试把GooglePlayGames库全部删掉,重新导入,重新执行上述两步。
二、登录失败
如果我们调用登录是这样写的:
PlayGamesPlatform.Instance.Authenticate();
在某些情况,可能会返回失败,这时我们在失败中,再加入下面这句,是可以成功。
PlayGamesPlatform.Instance.ManuallyAuthenticate();
四、签名问题
我们可能会遇到打的APK可以登陆,但打的aab包,或从商店下载的包无法登陆;我们把证书指纹修改为发布证书,导致APK又无法登陆,都是因为证书问题
正确配置需要有两个凭据
一个对应调试证书
一个对应发布证书
有两个凭据,需要有一个勾选:“新安装的应用将使用此凭据”
按照谷歌的说法,应该是发布证书勾选才对,但实际,从商店下载的包会登陆失败,最后我尝试将调试证书勾选,莫名其秒的成功了,无论是APK,还是从商店下载的,都没有问题。具体什么原因,我没有搞明白,如果哪位知道原因,请在评论区留言,感谢!
四、手机中必须安装Google Play 游戏APP
刚开始我手机中没有安装GooglePlay游戏APP,一直登入失败,导致我浪费了半天时间。
我们开发中也要考虑这个问题,如果玩家的手机没有安装,导致登陆失败,开发者应该处理这种情况。
这是我的登陆代码,供大家参教
- private bool manuallyAuthenticate = false;
-
- void Awake()
- {
- PlayGamesPlatform.Activate();
- }
-
- public override void Login() {
- SDKChannel.SDKLog($"点击登陆");
-
- manuallyAuthenticate = false;
- PlayGamesPlatform.Instance.Authenticate(OnAuthenticationFinished);
- }
-
- private void OnAuthenticationFinished(SignInStatus status)
- {
- SDKChannel.SDKLog($"登陆回调 status:{status}");
- if (status == SignInStatus.Success)
- {
- JObject callObj = new JObject();
- callObj["UserId"] = PlayGamesPlatform.Instance.GetUserId(); //用户ID
- callObj["UserName"] = PlayGamesPlatform.Instance.GetUserDisplayName(); //用户名字
- SDKChannel.OnSDKCallback((int)ESDKCallType.LoginSuccess, callObj);
- }
- else
- {
- if (manuallyAuthenticate == false)
- {
- PlayGamesPlatform.Instance.ManuallyAuthenticate(OnAuthenticationFinished);
- manuallyAuthenticate = true;
- }
- else
- {
- JObject callObj = new JObject();
- callObj["Status"] = status.ToString(); //状态
- SDKChannel.OnSDKCallback((int)ESDKCallType.LoginFailure, callObj);
- }
- }
- }

五、云存储
刚开始我的写法是,在游戏启动时,打开游戏存储(OpenSaveGame),把获得到的game(ISavedGameMetadata game)对象存起来,在游戏中每1分钟调用一次保存游戏(SaveGame)
听上去没有问题,平时的编程思路都是这样
但实际测试,每打开一次游戏存储(OpenSaveGame)时获得的game对象,在保存时,只能使用一次
即:每次保存,必须先去打开游戏对象
这让我有点难以理解,但实际测试是这个样子,如果我的理解有错,欢迎评论留言。
云存储完整代码
- /// <summary>
- /// 保存玩家游戏数据
- /// </summary>
- public class SDKGameDataGoogle
- {
- private static SDKGameDataGoogle _instance;
-
- public static SDKGameDataGoogle Instance
- {
- get
- {
- if (_instance == null)
- {
- _instance = new SDKGameDataGoogle();
- }
-
- return _instance;
- }
- }
-
- private bool _isSaveing;
- private Action _action;
-
- private JObject _saveJObject;
-
- private string filename = "data1";
-
- //打开游戏存档
- public void OpenGame(Action action)
- {
- _isSaveing = false;
- _action = action;
-
- Debug.Log($"11 打开游戏存档");
-
- if (!this.OpenSavedGame())
- {
- _action?.Invoke();
- }
- }
-
- public void SaveGame(JObject jObject)
- {
- _isSaveing = true;
- _saveJObject = jObject;
-
- Debug.Log($"11 保存游戏存档");
- this.OpenSavedGame();
- }
-
- private bool OpenSavedGame()
- {
- if (PlayGamesPlatform.Instance == null || PlayGamesPlatform.Instance.SavedGame == null)
- {
- return false;
- }
- ISavedGameClient savedGameClient = PlayGamesPlatform.Instance.SavedGame;
- savedGameClient.OpenWithAutomaticConflictResolution(filename, DataSource.ReadCacheOrNetwork,
- ConflictResolutionStrategy.UseOriginal, OnSavedGameOpened);
- return true;
- }
-
- //打开完成
- private void OnSavedGameOpened(SavedGameRequestStatus status, ISavedGameMetadata game) {
-
- Debug.Log($"打开保存的游戏--回调{status}");
-
- if (_isSaveing)
- {
- if (status == SavedGameRequestStatus.Success)
- {
- byte[] savedData = System.Text.Encoding.UTF8.GetBytes(this._saveJObject.ToJson(Formatting.None));
- this.SaveGame(game, savedData);
- }
- }
- else
- {
- if (status == SavedGameRequestStatus.Success)
- {
- ISavedGameClient savedGameClient = PlayGamesPlatform.Instance.SavedGame;
- savedGameClient.ReadBinaryData(game, OnSavedGameDataRead);
- }
- else
- {
- _action?.Invoke();
- }
- }
- }
-
- //拿到元数据
- private void OnSavedGameDataRead (SavedGameRequestStatus status, byte[] data) {
- Logger.LogError($"拿到玩家数据, status:{status}, data.length:{data.Length}");
- if (status == SavedGameRequestStatus.Success)
- {
- JObject jObject = null;
- try
- {
- string json = System.Text.Encoding.UTF8.GetString(data);
- jObject = JObject.Parse(json);
- }
- catch (Exception e)
- {
- jObject = new JObject();
- }
-
- CSPlayerSettings.InitializedPlayerData(jObject, "googleplaygames", PlayGamesPlatform.Instance.GetUserId());
- }
- _action?.Invoke();
- }
-
- private void SaveGame(ISavedGameMetadata game, byte[] savedData) {
- Debug.Log($"22 保存游戏存档");
- ISavedGameClient savedGameClient = PlayGamesPlatform.Instance.SavedGame;
-
- SavedGameMetadataUpdate.Builder builder = new SavedGameMetadataUpdate.Builder();
- builder = builder.WithUpdatedDescription("Saved game at " + DateTime.Now);
-
- SavedGameMetadataUpdate updatedMetadata = builder.Build();
- savedGameClient.CommitUpdate(game, updatedMetadata, savedData, OnSavedGameWritten);
- }
-
- private void OnSavedGameWritten (SavedGameRequestStatus status, ISavedGameMetadata game) {
- Debug.Log($"33 保存游戏存档结果:{status}");
- }
- }

文章最后,吐槽一下Unity提供的CloudData
最初我的想法是,接入GoogleSign与Unity的CloudData实现登陆与存储玩家数据,GoogleSign以前已经接过,不用再踩坑,另外发布苹果时,就不用再写一遍苹果存储问题。
一切进行的都很顺利,测试也都通过了,但在两天后,请求加载CloudData时,Unity返回错误:There was a validation error. Check 'Details' for more information
我拿着这个错误去Google搜索,一点资料也没有,尝试清理缓存,还是返回一样的错误。
在我测试的前两天都很正常,突然返回这个错误,且,一旦发生,就是不可逆的,玩家数据彻底丢失!
想不出原因后,无奈只得放弃,重新接入GooglePlayGames...(。•ˇ‸ˇ•。) ...
当然,如果有哪位大佬知道原因,请在评论区留言,感谢!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。