見出し画像

GameCenterのアチーブメントの送信がうまくいかない原因と対策

どうも、マカロンです。

今回はGameCenterのアチーブメントの送信がうまくいかない原因と対策について書いていこうと思います。

まあ2021年にこの機能をどのくらいの方が使用しているかは疑問ですが...
とりあえず書いていきます。



参考記事

kanさんの記事を参考に書いていきます。

記事ではアチーブメント送信の失敗について別の記事を紹介されていますが、この記事では使用しないのでそちらの確認は大丈夫です。




アチーブメントバグを解消したコード

以下kanさんのコードをベースに改良を加えたものになります。

//  iOSRankingUtility.cs
//
//  元 http://kan-kikuchi.hatenablog.com/entry/iOSRankingUtility
//  Created by kan.kikuchi on 2016.03.31.
//
//  改良版 https://note.com/08_14/n/n5b5161d5b699
//  Created by macaron on 2021.10.25.

using UnityEngine;
using UnityEngine.SocialPlatforms;
using System;
using System.Collections;
using System.Collections.Generic;
/// <summary>
/// iOSのランキング用便利クラス
/// </summary>
public static class iOSRankingUtility
{
   //=================================================================================
   //初期化
   //=================================================================================
   
   /// <summary>
   /// ユーザー認証
   /// </summary> 
   public static void Auth(Action<bool> callBack = null)
   {
       //コールバックが設定されていない場合はログを設定
       if (callBack == null)
       {
           callBack = (success) => {
               Debug.Log(success ? "認証成功" : "認証失敗");
           };
       }
       Social.localUser.Authenticate(callBack);
       //アチーブメント獲得時の通知をONにする
       UnityEngine.SocialPlatforms.GameCenter.GameCenterPlatform.ShowDefaultAchievementCompletionBanner(true);
   }
   
   //=================================================================================
   //ランキング
   //=================================================================================
   /// <summary>
   /// リーダーボードを表示する
   /// </summary>
   public static void ShowLeaderboardUI()
   {
       Social.ShowLeaderboardUI();
   }
   
   /// <summary>
   /// リーダーボードにスコアを送信する
   /// </summary>
   public static void ReportScore(string leaderboardID, long score, Action<bool> callBack = null)
   {
       //コールバックが設定されていない場合はログを設定
       if (callBack == null)
       {
           callBack = (success) => {
               Debug.Log(success ? "スコア送信成功" : "スコア送信失敗");
           };
       }
       //エディター上で送信すると、エラーが出るので、送信が成功したことにする
#if UNITY_EDITOR
       callBack(true);
#else
   //送信
   Social.ReportScore (score, leaderboardID, callBack);
#endif
   }
   
   //=================================================================================
   //実績
   //=================================================================================
   
   /// <summary>
   /// 実績一覧を表示する
   /// </summary>
   public static void ShowAchievementsUI()
   {
       Social.ShowAchievementsUI();
   }
   
   /// <summary>
   /// 実績の進捗状況を送信する
   /// </summary>
   public static void ReportProgress(string achievementKey, double percent, Action<bool> callBack = null)
   {
       //値が100を超えていたら100に戻す
       if (percent > 100) { percent = 100; }
       
       //アチーブメントのインスタンスを作成し、keyと進捗率を設定
       IAchievement achievement = Social.CreateAchievement();
       achievement.id = achievementKey;
       achievement.percentCompleted = percent;
       
       //コールバックが設定されていない場合はログを設定
       if (callBack == null)
       {
           callBack = (success) =>
           {
               Debug.Log(success ? "進捗送信成功" : "進捗送信失敗");
           };
       }
       
       //エディター上で送信すると、エラーが出るので、送信が成功したことにする
#if UNITY_EDITOR
       callBack(true);
#else
   //送信
   achievement.ReportProgress(callBack);
#endif
   }
}

変更した点は以下になります。
・関数 ReportProgressの引数percent(進捗率)をdoubleに変更
・percentが100を超えた時、値を100に戻す

の2点になります。




原因と対策

正常に送信が行われないのはachievement.percentCompletedが原因でした。

ここにはそのアチーブメントの進捗率が入り、その数値が100になると達成したことになりゲーム画面中央上あたりに通知がいきます。

この値が100%を超えてしまうとその通知が出なくなるみたいです。

ここの値は確率を見るものなので100%以上の値が入って
バグってしまうのは納得できます。

なのでfloatで100.0fなどの値を入れた場合それを自動的に100.0に変換しなくてならないのでその過程で送信が行われないなどの不具合が出たのかもしれません。




最後に

今回の記事で書いた内容以外の原因もあるのかもしれませんが、僕はひとまずこの方法で治りましたので、参考までによろしくお願いします^^

ではまた


ゲームを作るにはやはりお金がないとできることが限られてしまいます。なのでよろしければどうか支援してくださるとうれしいです