※ これは 2021/04/02 時点の Unity 2020.3.2f1, Xcode 12.4 の情報です
最新版では動作が異なる可能性がありますのでご注意ください
NavMesh を利用した 2D キャラ動作はだいたいやりたいことができたので、今度は別のことを試してみる
ついに始まったらしいこれについて
2021年4月末までの対応必須化が噂されるため iOS 14 の App Tracking Transparency 対応 を Unity で実装してみたい
スポンサードリンク
まずは下記のように Bootstrap
という名前で初期シーンの Hierarchy 上に GameObject を追加
この GameObject には下記のような Bootstrap.cs
というスクリプトをアタッチする
using UnityEngine; public class Bootstrap : MonoBehaviour { /// <summary> /// 開始処理 /// </summary> public async void Start() { #if UNITY_IOS && !UNITY_EDITOR var status = NativeService.GetIOSTrackingAuthorizationStatus(); // 未回答だった場合は ATT 許可要求ダイアログを表示 if (!status.HasValue) { status = await NativeService.RequestTrackingAuthorization() as bool?; } if (status.Value) { //TODO: 許可時の処理 } else { //TODO: 不許可時の処理 } #endif } }
アプリ起動時に ATT 許可状態を調べて、未回答だった場合許可要求ダイアログを表示して結果に応じた分岐をさせるだけ
ここで呼び出されている NativeService.cs
は下記のような感じ
using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; public class NativeService { private static TaskCompletionSource<bool> AttTcs; private static SynchronizationContext Context; static NativeService() { Context = SynchronizationContext.Current; } #if UNITY_IOS /// <summary> /// ATT 許可状態取得 /// </summary> /// <returns></returns> [DllImport("__Internal")] private static extern int GetTrackingAuthorizationStatus(); private delegate void OnCompleteStatusCallback(int status); /// <summary> /// ATT 許可要求 /// </summary> /// <returns></returns> [DllImport("__Internal")] private static extern int RequestTrackingAuthorization(OnCompleteStatusCallback callback); /// <summary> /// ATT の同意状態を取得する /// </summary> /// <returns></returns> public static bool? GetIOSTrackingAuthorizationStatus() { #if UNITY_EDITOR return true; #else switch (GetTrackingAuthorizationStatus()) { case -1: // No Needs case 3: // Authorized return true; case 0: // Not Determined return null; default: return false; } #endif } /// <summary> /// /// </summary> /// <returns></returns> public static Task<bool> RequestTrackingAuthorization() { #if UNITY_EDITOR return Task.FromResult(true); #else AttTcs = new TaskCompletionSource<bool>(); RequestTrackingAuthorization(OnRequestTrackingAuthorizationComplete); return AttTcs.Task; #endif } [AOT.MonoPInvokeCallback(typeof(OnCompleteStatusCallback))] private static void OnRequestTrackingAuthorizationComplete(int status) { if (AttTcs != null) { Context.Post(_ => { switch (status) { case -1: // No Needs case 3: // Authorized AttTcs.TrySetResult(true); break; default: AttTcs.TrySetResult(false); break; } }, null); } } #endif }
iOS のネイティブプラグインを呼び出して戻り値を橋渡ししている
さらにこの NativeService
が呼び出すプラグインスクリプトを NativeService.mm
という名前で Assets/Plugins/iOS
ディレクトリ配下に作成
中身はこんな感じ
#import <Foundation/Foundation.h> #import <AppTrackingTransparency/ATTrackingManager.h> #ifdef __cplusplus extern "C" { #endif // ATT 許可状態取得 // 0: Not Determined, 1: Restricted, 2: Denied, 3: Authorized, -1: No Needs int GetTrackingAuthorizationStatus(){ if (@available(iOS 14, *)) { return (int)ATTrackingManager.trackingAuthorizationStatus; } else { return -1; } } typedef void (*Callback)(int status); // ATT 許可要求 // 0: Not Determined, 1: Restricted, 2: Denied, 3: Authorized, -1: No Needs void RequestTrackingAuthorization(Callback callback) { if (@available(iOS 14, *)) { [ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus status) { if (callback != nil) { callback((int)status); } }]; } else { callback(-1); } } #ifdef __cplusplus } #endif
あとは iOS のビルドだけ・・・だけども Xcode 用のプロジェクトを出力後、中身を開いて追加の作業手順が必要
UnityFramework
のターゲットプロジェクトを選択し、AppTrackingTrasparency.framework
への参照を追加する
さらに Unity-iPhone
のターゲットプロジェクトを選択し、Info.plist に Privacy - Tracking Usage Description
を追加
中身は収集するユーザーデータの利用目的を記載していないと Apple の審査でリジェクトされる
「上記は広告表示や利用状況の分析に使用します」という文言にした
ここまでやったらビルドして iPhone の実機で動かしてみると・・・
ちゃんと表示されたね