そういうのがいいブログ

アプリ個人開発 まるブログ

アプリ開発覚え書き

【Unity】多言語化パッケージ Localization スクリプトなしで言語毎にフォントサイズを設定する方法

環境

Unity 2022.3.10f1 (シリコン)
Localization 1.4.5

はじめに

以下の記事で言語毎にテキストを変更することができました。

marumaro7.hatenablog.com

言語によって文字数が異なるため
フォントサイズを変更したくなるときがあります。
今回はそのような場合に設定する方法です。

方法

まずはLocalization Scene Controlsを表示します。

→ウインドウ
→アセット管理
→Localization Scene Controls


このウインドウのTrack Changesにチェックを入れた状態で
設定言語のフォントサイズを変更するだけで
その言語のみのフォントサイズを設定することができます。


実際にやってみます。
通常のフォントサイズは40
日本語のフォントサイズ30にて設定してみます。

通常のフォントサイズは40になっています。


言語を日本語に切り替え


フォントサイズを30へ変更します。
するとフォントサイズを入力する欄が緑色になり言語毎の設定対象となります。

これで設定完了です!
他の言語も設定したい場合は同様に設定するのみです。


部分設定の頻度はそこまで高くないと思いますので
設定後はTrack Changesのチェックは外しておいた方がよいでしょう。


設定を解除したい場合はFontSizeで右クリック
「Remove Localized Property」をクリックすることで解除できます。

おわりに

スクリプトを書かずに設定ができるのが良いですね!

本出版しました!

marumaro7.hatenablog.com

【Unity】多言語化パッケージ Localization 言語毎にフォントアセットを切り替える方法

環境

Unity 2022.3.15f1 (シリコン)
Localization 1.4.5
UniTask 2.5.0

はじめに

言語化パッケージ Localizationを使用して言語を切り替えることができますが
フォントが翻訳した言語に対応していないと表示ができません。

対応言語が日本語と英語だけなら特に問題ありませんが
アラビア語などに対応しようするとフォントアセットも
言語に応じて切り替える必要があります。

最適解ではないですが対応方法をメモしておきます。

テキストはTextMeshProを使用する前提で書きます。

注)メモが目的なので雑に書いてしまっています。

方法

次の3ステップです。
1.フォントアセット作成
2.スクリプト作成
3.スクリプト割当て

1.フォントアセット作成

対応する言語に応じたフォントアセットを用意します。

marumaro7.hatenablog.com


2.スクリプト作成

スクリプトは2つ作成します。(UniTaskを使用します。(コルーチンで代用可))
・言語が切り替わったらフォントアセットを切り替えるスクリプト
・フォントアセットを切り替えたいTextMeshProを登録するスクリプト

・言語が切り替わったらフォントアセットを切り替えるスクリプト
FontManagerという名前で作成しました。

using System.Collections.Generic;
using UnityEngine;
using TMPro;
using UnityEngine.Localization.Settings;
using UnityEngine.Localization;
using System;
using UnityEngine.SceneManagement;
using Cysharp.Threading.Tasks;

public enum SupportedLanguage
{
    ar, // アラビア語
    bn, // ベンガル語(バングラ語)
    zh_Hans, // 簡体字中国語
    zh_Hant, // 繁体字中国語
    en, // 英語
    fr, // フランス語
    de, // ドイツ語
    hi, // ヒンディー語
    id, // インドネシア語
    it, // イタリア語
    ja, // 日本語
    ko, // 韓国語
    mr_IN, // マラーティー語
    pt, // ポルトガル語
    ru, // ロシア語
    es, // スペイン語
    ta, // タミル語
    te, // テルグ語
    tr, // トルコ語
    ur // ウルドゥー語
}


// シリアライズ可能なクラスで、各言語と対応するTMP_FontAssetをマッピングします。
[System.Serializable]
public class FontAssetMapping
{
    public SupportedLanguage language; // SupportedLanguage 列挙型
    public TMP_FontAsset fontAsset;    // その言語のフォントアセット
}

// フォントを管理するためのマネージャークラス
public class FontManager : MonoBehaviour
{
    // シングルトンインスタンス
    public static FontManager Instance { get; private set; }

    // 各言語とフォントアセットのマッピング配列
    public FontAssetMapping[] fontMappings;

    // 登録されたTextMeshProUGUIコンポーネントのリスト
    [SerializeField] private List<TextMeshProUGUI> registeredTexts = new List<TextMeshProUGUI>();

    // 起動時の処理
    private void Awake()
    {
        // 既にインスタンスが存在していたら、重複を防ぐために破棄
        if (Instance != null && Instance != this)
        {
            Destroy(gameObject);
            return;
        }

        // シングルトンインスタンスを設定
        Instance = this;

        // シーンを跨いでも破棄されないように設定
        DontDestroyOnLoad(gameObject);


        // ロケール変更イベントの購読
        LocalizationSettings.SelectedLocaleChanged += OnLocaleChanged;

        // 現在のロケールに基づいてフォントを設定
        SetFontForCurrentLocale();

        // 新しいシーンが読み込まれたときのイベントに登録
        SceneManager.sceneLoaded += OnSceneLoaded;
    }


    public void SetFontForCurrentLocale()
    {
        // 現在のロケールを取得
        Locale currentLocale = LocalizationSettings.SelectedLocale;

        if (currentLocale != null)
        {
            // 現在のロケールに基づいてフォントを設定
            OnLocaleChanged(currentLocale);
        }
    }

    // TextMeshProUGUIコンポーネントを登録するためのメソッド
    public void RegisterTextMeshPro(TextMeshProUGUI tmp)
    {
        // 既にリストに含まれていなければ追加
        if (!registeredTexts.Contains(tmp))
        {
            registeredTexts.Add(tmp);
        }
    }

    // オブジェクトが破棄されるときの処理
    private void OnDestroy()
    {
        // イベントハンドラの登録解除
        LocalizationSettings.SelectedLocaleChanged -= OnLocaleChanged;
    }


    
    private async void OnSceneLoaded(Scene scene, LoadSceneMode mode)
    {
        // 0.2秒遅延 遅延させないと先に処理が実行されてしまってフォントアセットが切り替わらない。
        await UniTask.Delay(TimeSpan.FromSeconds(0.2f));

        // 遅延後の処理
        // 例: 現在のロケールに基づいてフォントを設定
        SetFontForCurrentLocale();

        // 必要に応じて他の処理をここに追加
    }
    

    private void OnLocaleChanged(Locale newLocale)
    {
        SupportedLanguage currentLanguage = (SupportedLanguage)Enum.Parse(typeof(SupportedLanguage), newLocale.Identifier.Code.Replace("-", "_"));
        TMP_FontAsset targetFontAsset = null;

        foreach (var mapping in fontMappings)
        {
            if (mapping.language == currentLanguage)
            {
                targetFontAsset = mapping.fontAsset;
                break;
            }
        }

        if (targetFontAsset != null)
        {
            foreach (var tmp in registeredTexts)
            {
                tmp.font = targetFontAsset;
            }
        }


    }

}


・フォントアセットを切り替えたいTextMeshProを登録するスクリプト
TMPFontRegistrarという名前で作成しました。

using UnityEngine;
using TMPro;

public class TMPFontRegistrar : MonoBehaviour
{
    private void Start()
    {
        // FontManagerが存在し、このオブジェクトにTextMeshProUGUIコンポーネントがある場合、
        // このTextMeshProUGUIをFontManagerに登録する
        var textMeshPro = GetComponent<TextMeshProUGUI>();
        if (FontManager.Instance != null && textMeshPro != null)
        {
            FontManager.Instance.RegisterTextMeshPro(textMeshPro);

            //途中でテキストがアクティブになった場合はフォントが適用されないため
            //フォント設定の関数を実行
            FontManager.Instance.SetFontForCurrentLocale();
        }
    }
}

3.スクリプト割当て

空のオブジェクトを作成しFontManagerのスクリプトを割り当て

FontMappingsの欄で
切り替えたい言語コード言語の選択と
言語コードに対応するフォントアセットを割り当てます。


あとは言語切り替えの対象としている
Localize String Eventを付けたオブジェクトに
TMPFontRegistrarのスクリプトを割り付けます。

※言語切り替えの設定方法は以下で解説しています。 marumaro7.hatenablog.com


確認

これで実行中に言語を切り替えると
フォントアセットが切り替わります。
シーン切り替えに対応していますので最初に読み込むシーンに
FontManagerを設置すると良いでしょう。

今回の方法は再生ボタンで実行しなければフォントアセットが切り替わりません。
そのため、テキスト表示の確認方法は次の2つです。
・実行してから言語を切り替える
・オブジェクトのフォントアセットを一時的に手動で切り替える
確認が少し面倒ですが今はこれが一番手間が少ないと考えているので
私はこの方法で進みます。


今回の方法までに失敗したこと

TextMeshProのインスペクターにて
フォントアセットの欄にて右クリック
→LocalizePropertyをクリック
→追加されるGameObjectLocalizer
こちらを利用することで言語に応じたフォントアセットを切り替えることができますが
切り替えタイミングが言語と同じタイミングで行われるようで
文字化けして使用できませんでした。

【Unity】TextMeshPro フォントアセットメモ

はじめに

TextMeshProを使用する場合、フォント毎にフォントアセットを作成します。
下記の言語に対応する際のフォントアセット作成メモです。

言語 日本語読み方
Arabic (ar) アラビア語
Bangla (bn) ベンガル語バングラ語)
Chinese (Simplified) (zh-Hans) 簡体字中国語
Chinese (Traditional) (zh-Hant) 繁体字中国語
English (en) 英語
French (fr) フランス語
German (de) ドイツ語
Hindi (hi) ヒンディー語
Indonesian (id) インドネシア語
Italian (it) イタリア語
Japanese (ja) 日本語
Korean (ko) 韓国語
Marathi (India) (mr-IN) マラーティー
Portuguese (pt) ポルトガル語
Russian (ru) ロシア語
Spanish (es) スペイン語
Tamil (ta) タミル語
Telugu (te) テルグ語
Turkish (tr) トルコ語
Urdu (ur) ×ウルドゥー語(追記:不要)

フォントアセットを作成する方法はこちらの記事を参考にします。

createdevelopmentnote.com


使用するフォント

なるべくフォントアセットはまとめたいため
次の言語のフォントアセットは共通にします。

・Noto Sans
英語
フランス語
ドイツ語
インドネシア語
イタリア語
ポルトガル語
ロシア語
スペイン語
トルコ語
ウルドゥー語
(Unityではウルドゥー語が透明になって表示できなかったため
 ウルドゥー語は英語表記で対応することにしました)

・ Noto Sans Devanagari
ヒンディー語
マラーティー

言語と使用するフォントは以下の想定で進めます。

言語 日本語読み方 使用フォント
Arabic (ar) アラビア語 Noto Kufi Arabic
Bangla (bn) ベンガル語バングラ語) Noto Sans Bengali
Chinese (Simplified) (zh-Hans) 簡体字中国語 Noto Sans Simplified Chinese
Chinese (Traditional) (zh-Hant) 繁体字中国語 Noto Sans Traditional Chinese
English (en) 英語 Noto Sans
French (fr) フランス語 Noto Sans
German (de) ドイツ語 Noto Sans
Hindi (hi) ヒンディー語 Noto Sans Devanagari
Indonesian (id) インドネシア語 Noto Sans
Italian (it) イタリア語 Noto Sans
Japanese (ja) 日本語 Noto Sans JP
Korean (ko) 韓国語 Noto Sans Korean
Marathi (India) (mr-IN) マラーティー Noto Sans Devanagari
Portuguese (pt) ポルトガル語 Noto Sans
Russian (ru) ロシア語 Noto Sans
Spanish (es) スペイン語 Noto Sans
Tamil (ta) タミル語 Noto Sans Tamil
Telugu (te) テルグ語 Noto Sans Telugu
Turkish (tr) トルコ語 Noto Sans
Urdu (ur) ウルドゥー語 Noto Nastaliq Urdu → Noto Sans


使用するフォントのファイル名は以下です。

言語
NotoKufiArabic-Medium
NotoSans-Medium
NotoSansBengali-Medium
NotoSansDevanagari-Medium
NotoSansJP-Medium
NotoSansKR-Medium
NotoSansSC-Medium
NotoSansTamil-Medium
NotoSansTC-Medium
NotoSansTelugu-Medium


フォントアセット作成

簡体字中国語、繁体字中国語、日本語、韓国語は
登録する文字数が多くアプリ容量が増加するため都度必要な分だけ登録することにします。

アプリ完成後、使用している単語を下記サイト様に入力し重複文字を削除して登録します。

tools.ikunaga.net

日本語は仮でこちらのテキストを設定しておくと開発中に困ることはないでしょう。
(作成者様に感謝)


Sampling Point Size/Paddingは10%がUnityさんおすすめのようです。
この比率が低いとフォントサイズを大きくした場合にぼやける模様(未検証)
以下で設定することにします。
Sampling Point Size:50
Padding:5


フォントアセット作成後
「スケール」と「行の高さ」、「ベースライン」を調節し
フォントアセット毎の文字の大きさと位置を微調整します。


以下はフォントアセット作成時の文字内容と
「スケール」、「行の高さ」、「ベースライン」です。


Noto Kufi Arabic

ءآأؤإئابةتثجحخدذرزسشصضطظعغفقكلمنهوىي
٠١٢٣٤٥٦٧٨٩
0123456789
،؛؟

Atlas Resolution 512×512

スケール:0.75
行の高さ:80
ベースライン:0



Noto Sans

ABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz
ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞß
àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ
АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ
абвгдеёжзийклмнопрстуфхцчшщъыьэюя
0123456789
!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~

Atlas Resolution 1024×1024

スケール:1
行の高さ:65
ベースライン:0



Noto Sans Bengali

অআইঈউঊঋএঐওঔকখগঘঙচছজঝঞটঠডঢণতথদধনপফবভমযরলশষসহ়ঽািীুূৃেৈোৌ্ৎৗড়ঢ়য়০১২৩৪৫৬৭৮৯
0123456789
,;?!

Atlas Resolution 512×512

スケール:1
行の高さ:64
ベースライン:0



Noto Sans Devanagari

अआइईउऊऋऌऍऎएऐऑऒओऔकखगघङचछजझञटठडढणतथदधनपफबभमयरलवशषसहऽािीुूृॄॅॆेैॉॊोौ्ॐ॒॑॓॔ॕॖॗक़ख़ग़ज़ड़ढ़फ़य़ॠॡॢॣ०१२३४५६७८९
0123456789
!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~

Atlas Resolution 512×512

スケール:1
行の高さ:63
ベースライン:0



Noto Sans Tamil

அஆஇஈஉஊஎஏஐஒஓகஙசஜஞடணதநனபமயரறலளழவஶஷஸஹாிீுூெேைொோௌ்ௐ௦௧௨௩௪௫௬௭௮௯
0123456789
!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~

Atlas Resolution 512×512

スケール:1
行の高さ:62
ベースライン:-9.8



Noto Sans Telugu

అఆఇఈఉఊఋఎఏఐఒఓకఖగఘఙచఛజఝఞటఠడఢణతథదధనపఫబభమయరఱలవశషసహాిీుూృౄెేైొోౌ్ౕౖౠౡౢౣ౦౧౨౩౪౫౬౭౮౯ం
0123456789
!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~

Atlas Resolution 512×512

スケール:1
行の高さ:67.6
ベースライン:-4



×Noto Nastaliq Urdu
×大部分が透明になって表示できないため作成しない

آبپتٹثجچحخدڈذرڑزژسشصضطظعغفقکگلمنںوؤہھیئۓ
٠١٢٣٤٥٦٧٨٩
0123456789
!،؛؟:؍’‘“”؎؏-–—



Noto Sans JP
文字内容:適宜設定
スケール:1
行の高さ:60
ベースライン:0

おわりに

仮で作成したので表示できない文字が出てきたら随時追加していきたいと思います。

また、/(スラッシュ)はNoto Kufi Arabicのフォントなどで存在しないため
100/100といった表現はフォントを分けるか使わない方がよさそうです。

参考

qiita.com

【Unity】多言語化パッケージ Localization CSVファイル出力→編集→入力してなるべく楽に多言語化対応する方法

環境

Unity 2022.3.15f1 (シリコン)
Localization 1.4.5
macOS Ventura 13.4
Numbers 13.1

はじめに

以下の記事内では日本語と英語についての設定方法でした。

marumaro7.hatenablog.com

言語化する言語数が2つ3つならエディター内に直接打ち込んでいけば
なんとか対応できそうですが、20言語の多言語化を実施しようとすると
エディター内に打ち込んでいくのはさすがに大変すぎるので
ファイルを出力して少しでも編集の楽をしようとする話です。

↓20言語を設定する時の設定画面(設定項目ありすぎ...)

方法

次の3ステップで実施します。
1.設定内容をCSVファイルで出力する
2.CSVファイルを編集する
3.CSVファイルの内容をUnity側へ反映する

1.設定内容をCSVファイルで出力する

編集したいテーブルをCSVファイルで出力します。

キーとその内容の登録画面を開きます。
→ウインドウ
→アセット管理
→Localization Tables

設定画面が開いたら
「Selected Table Collection」の項目で対象のテーブルを選択します。

画面右上の縦点3つのボタンを押し、
→Export
CSV

好きな場所に保存します。(今回はデスクトップに保存)

これでCSVファイルの出力は完了です。

2.CSVファイルを編集する

出力したCSVファイルを開くとこのようになります。
Mac環境、Numbersで開いた場合のため Windowsでは表示が異なるかもしれません。)

idという列は自動で値が付与されるため触らずに
各言語のセルに対応した文字を入力していきます。


CSVで出力したことで
翻訳サイトDeepLおよびGoogle翻訳
まとめての翻訳とセルへの値貼り付けが可能になります。

日本語のテキストを"スタート"、"スキル発動"とした場合、

まとめて翻訳、結果をまるごとコピーし


セルにまとめて貼り付けができます。

これを繰り返してファイルを完成させます。


編集が終了したらCSVファイルを書き出しておきます。
→ファイル
→書き出す
CSV

→保存

3.CSVファイルの内容をUnity側へ反映する

あとはCSVファイルを取り込むだけです。

Localization Tablesのウインドウにて
(→ウインドウ)
(→アセット管理)
(→Localization Tables)

画面右上の縦点3つのボタンを押し、
→Import
CSV

取り込むCSVファイルを指定すると、、、

このように設定を取り込むことが可能です。(今回は日本語と英語のみ設定)

おわりに

CSVの編集についてプログラムで自動化できるようですが
学習コストが高そうなのでチャレンジしませんでした。

今回の方法でも一つずつ翻訳をかけるよりだいぶ時短になるはずです。
私はアニメでも見ながら片手間で対応していくつもりです。

次は言語毎にフォントを切り替える話(作成中・・・)

本出版しました

marumaro7.hatenablog.com

【Unity】プロジェクトのバージョン管理をする方法2 -基本操作- Git GitHub SourceTree 

はじめに

前回の記事で初期設定まで完了しました。

marumaro7.hatenablog.com

今回は下記の利用シチュエーションへの対応メモになります。

利用シチュエーション
・進捗の保存(コミット)
・特定のコミットまでのコミットを消す(ハードリセット)
・コミットを切り替える(チェックアウト)
・特定のコミット内容をなかったことにする(リバート)
GitHubにアップロード(プッシュ)

進捗の保存 (コミット)

進捗を保存する方法です。
任意のタイミングでコミットをしていくだけです。
実際にやってみます。

Unityでプロジェクトを開いてCubeオブジェクトを設置し保存しました。
その後、Unityを閉じます。


Unityを閉じ、SourceTreeで対象のリポジトリを開くと次のように変更点が表示されます。


全部のファイルを選択し、「コミット」を押すことで
今回のUnity側での変更を保存することができます。
コメントは「Cube追加」としました。


履歴を確認すると今回のコミットが一番上に表示されています。

特定のコミットまでのコミットを消す(ハードリセット)

不具合発生時などに
過去のコミットしたところまでプロジェクトを戻す方法です。

先程のプロジェクトをUnityで開き、「Plane」を追加しました。


ではここからPlaneが設置される前(先ほどコミットした状態)に戻していきます。
SourceTreeの履歴のところでいうと「Cube追加」の状態になります。


履歴から戻りたいコミットを選択し右クリック
「masterをこのコミットまで戻す」を押します。


現在のデータは残すのかを聞かれます。
コミット後のデータは不要なため「Hard」を選択して「OK」を押します。


作業中のデータが消えますよ〜の警告ウインドウが出ますので
「OK」を押します。


履歴の画面の最上部に表示されていた
「Uncommitted changes」の文字が消え、
グラフ列の白丸が「cube追加」のコミットにずれています。

<追記>
最上部の「Uncommitted changes」の文字が消えない場合は
一旦コミットしてから戻りたいコミットで
「masterをこのコミットまで戻す」を実施すると処理できました。


プロジェクトを開くと、
先ほど追加したPlaneが消えてコミットした時点までプロジェクトが戻ります。

複数のコミットをまたがって遡る場合、
途中に存在するコミットが消えてしまうため
慎重に操作を実施する必要があります。

コミット内容を確認する場合は、下記の「コミットの切り替え」を実施することで可能です。


コミットの切り替え(チェックアウト)

特定のコミットの状態へ切り替える方法になります。
不具合の原因特定に役立てられます。

説明をわかりやすくするため
Cubeを増やしたプロジェクト内容のコミットを用意しておきます。

Cubeを新たに3つ配置し、Unityを保存して閉じます。


Cubeを コミット後、履歴を確認すると画像のようになります。


履歴の画面から切り替えたいコミットを選択し 右クリック→「チェックアウト」を選択します。


→「OK」を押します。


白い丸が「Cube追加」のコミットに移動しました。


Unityを開くとCubeを一つだけ配置したコミットに戻っていることが確認できます。


再度チェックアウトを実施し、先頭のコミットに切り替えてみます。


白い丸が「Cubeを3つ追加」に移動したことがわかります。


Unityを開くとコミットが切り替えられていることが確認できました。


このようにチェックアウトを実施することで
特定のコミットの状態に切り替えることが可能です。


コミットしていないデータがある場合、
チェックアウト後、

「ローカルの変更を破棄」にチェックをつけてOKを押すことで切り替え可能です。
(チェックをつけないと競合しているというエラーがでます。)


実行後、コミットしていないデータが消され、切り替わります。


特定のコミット内容をなかったことにする(リバート)

あまり使わない気がしますので、メモ書き程度に残しておきます。
特定のコミット内容をなかったことにする処理です。

「Cubeを3つ追加」のコミットが反映されている状態から実施していきます。

AScriptという名前のスクリプトを追加したとします。
保存してUnityを閉じます。


「AScript追加」というコメントでコミットします。


BScriptという名前のスクリプトを追加 保存してUnityを閉じます。


「BScript追加」というコメントでコミットします。


この状態の時にAScriptを除いたコミットを作成する方法です。
「AScript追加」のコミットを選択し、右クリック→「コミット適用前に戻す」を選択


確認画面は「OK」を選択


処理が完了すると AScriptのコミット内容が除かれた新しいコミットが作成されます。

Unityで開くと、AScriptがなくなっていることがわかります。

このように特定のコミット内容をなかったことにするのが今回の処理内容となります。

注意
なかったことにできるのは、シーンに直接紐づいていないコミットになります。
オブジェクトを追加したりスクリプトの割り当てといった
シーンの中身を変化させるコミットの場合はエラーが発生し、新しいコミットは作成されませんでした。

そのため、あまりこの内容は使う場面はないのかなと考えています。


GitHubにアップロード(プッシュ)

PC破損リスクヘッジとプロジェクト使い回しのため
特定のコミットをGitHubのリモートリポジトリに送信します。
前回の記事で実施していますが改めて書きます。

画面上部のプッシュを実施します。


「OK」


処理が完了すると「origin/master」が最後のコミットへ移動します。


GitHubの該当リポジトリにて、
masterタブに切り替えてみると「Revert "AScript追加"」のコミットが反映されています。

おわりに

基本は適宜コミットをしてたまにGitHubへアップロードしていく使い方になりそうですね。

ひとつでも得るものがありましたら幸いです。

本出版しました

marumaro7.hatenablog.com

【Unity】プロジェクトのバージョン管理をする方法1 -ツール導入〜プロジェクト初期設定- Git GitHub SourceTree 

前提

Xcodeをインストール済み
macOS Ventura13.4

はじめに

Unityプロジェクトのバージョン管理をする方法のメモです。

今までバージョン管理についてちゃんとやっていなかったのですが、
ネット上にバックアップをとりながら開発を進めるためようやく始めました。

今回はツールの導入からプロジェクト初期設定までを書きます。



導入後の基本操作はこちらです。 marumaro7.hatenablog.com

環境構築

今回使用するツール・サービスは以下です。
ざっくり説明
・Git(無料)
 バージョン管理をするツール ローカルに保存

GitHub(基本は無料)
 Gitのバージョン情報をオンラインで保存する場所

・SourceTree(無料)
 Gitの操作はコードを打ち込む形式なので操作がわかりづらい。
 そのため、ボタンで視覚的に操作可能にしてくれるのがこのSourceTree

Gitの導入確認

Xcodeをインストール済みであれば自動でgitがインストールされているはずです。

ターミナル(Macの標準アプリケーション)を開き、
下記を打ち込んでgitのバージョンが表示されればOK

git --version

実際に打ち込んでみたところ次のように表示されました。
git version 2.39.2(Apple Git-143)

参考 qiita.com

GitHubアカウント作成

次にGitHubアカウント作成します。
私は作成済みであったため、本記事では手順を省略します。

新規作成の方はこちらが参考になりそうです。 reffect.co.jp

SourceTreeの導入

最後にSourceTreeを導入します。

1.SourceTreeのサイトにアクセス
www.sourcetreeapp.com


2.「Download for Mac OS X」をクリック


3.プライボシーポリシーにチェックを付けダウンロードボタンをクリック


4.アプリケーションを移動
ダウンロードフォルダにSourceTreeのアプリができているので
アプリケーションフォルダへ移動(使いやすい場所でOKです)


5.アプリケーションを起動
注意ウインドウが出た場合は「開く」をクリックします。


6.Bitbucketとの連携 確認
アプリを開くとBitbucketと連携する画面が出てきますが
今回はGitHubを使用するため設定せずに「続行」を押します。
※BitbucketはGitHubのようなオンラインのデータを保存するサービスです。


7.作成者情報の入力
こちらの設定は、どのアカウントから変更されたのかをわかるようにするものです。
設定せずとも完了可能ですが、私は設定して進めました。
GitHubで登録した情報と同じにしておくのが一般的なようです。


このような画面になったら導入完了です!



GitHubとSourceTreeの連携

SourceTreeからGitHubに作成している情報を取り出したりするためには
GitHubでパーソナルアクセストークンを発行し、
SourceTreeに登録する必要があります。


パーソナルアクセストークン(PAT)生成手順

GitHubでアクセストークンを生成します。


画面右上にある自分のプロフィールアイコンをクリック


「Settings」をクリック


→左側のサイドバーから一番下の「Developer settings」をクリック


→Personal access tokens
→Tokens (classic)
→「Generate new token」
→「Generate new token (classic)」ボタンをクリックします


GitHubのパスワードを入力します。


必要事項を入力します。いろいろ項目がありますが、
今回の目的ですと以下で良いようです。

・Notes
 説明書きです。今回は、「Unity project version control」と記入しました。
 お好きな内容で問題ありません。

・Expiration
 有効期限です。お好きな期間を選択してください。
 「No expiration」で有効期限なしとすることもできますが非推奨です。

・repo
 SourceTreeからのバージョン管理に関する基本操作を行うための権限になります。
 「repo」にチェックを付けておきます。

・workflow
 GitHub Actionsのワークフローを更新する権限が必要な場合に選択します。
 場合によっては必要ないと思いますが今回は権限を付与して進めます。

入力後、一番下の「Generate token」ボタンを押してトークンを生成します。


生成されたトークンが表示されます。
このトークンは表示されるのはこの1回のみです。
必ずコピーしてわかる場所に保存してください。

SourceTreeとの連携

生成したアクセストークンをSourceTreeに登録して連携します。


SourceTreeのアプリを開き
→SourceTree
→設定


→アカウント
→追加(アカウントが既に登録されている場合、アカウントを選択して編集)


以下を入力/選択します。
ホスト         :GitHubを選択
認証タイプ       :Peronal Access Tokenを選択
ユーザー名       :GitHubのアカウント名を入力
Personal Access Token:先ほどGitHubで生成したトークンの文字列を入力
プロトコル       :HTTPSを選択
→「保存」


アカウントが登録されました。
これで設定完了です。


プロジェクト初期設定

実際に使用していきたいところですが
Gitで管理するうえで推奨の設定がありますので以下を設定していきます。
・Unityプロジェクト側の設定
・保存しないファイルの設定

1.Unityプロジェクトの作成

まずはバージョン管理するUnityプロジェクトを作成します。
プロジェクト名は「GitTestTest」にしました。

2.Unityプロジェクト側の設定

Unityのアセットとシーンファイルをテキスト形式で保存する設定を行います。
これによりファイルの差分をGitでより効果的に追跡できるようになります。

Unity画面
→編集
→プロジェクト設定


→エディター
→アセットシリアル化の項目 Modeを「ForceText」に変更
(Unity2022.3.10f1では始めから設定されていました。)


Unityを保存して閉じておきます。

3.保存しないファイルの設定

一時ファイルやビルドファイルなどはリポジトリに含める必要がないため
リポジトリに含まれないように設定する必要があります。

こちらの設定は、手動で設定することもできるのですが
一番簡単な方法はGitHubの設定を適用する方法になります。

そのため、GitHubも絡めて初期設定を進めます。


3.1.GitHub側の設定

1.GitHubにログインします。 github.com


右上の「+」ボタン
→「New repository」
※repository(リポジトリ)とは、情報を一元管理できる場所 という意味の単語です。


以下を入力/選択
・Repository name:プロジェクト名を入力
・Privateを選択
・Add .gitignoreの選択:Unityを選択
入力後、「Create repository」をクリック


するとリポジトリが作成され、このような画面になります。
.gitignoreというファイルが表示されているはずです。
.gitignoreにはどのファイルをGitで管理しないのかという内容が入っています。


(追記)
このタイミングでブランチ名をmain→masterへ変更しておけば
mainとmasterブランチが存在することがなさそうです。(未検証)
方法は後述

3.2.SourceTree側の設定

ここからUnityを閉じておく必要があります。
Unityが閉じていることを確認して進めてください。

3.2.1 ローカルリポジトリの作成

SourceTreeを起動
→新規
→ローカルリポジトリを作成


→「保存先のパス」は右側の「...」ボタンを押し対象のプロジェクトフォルダを選択
 (パスを指定すると名前が勝手にプロジェクト名に変更されます。)
→「作成」
(エラーが発生し保存できない場合はPC再起動で解決しました。)


成功すると以下のように一覧に表示されます。
次に「GitTestTest」をダブルクリックします。


このように表示されるはずです。


3.2.2 ローカルリポジトリとリモートリポジトリの接続

リモートリポジトリの場所をローカルリポジトリに登録します。

一旦GitHubの画面に戻り次の手順でURLをコピーします。
→Codeボタン
HTTPS
→URL横のコピーボタンを押す


SourceTreeに戻り
画面右上の「設定」
リモートタブをクリック


登録画面が開くので以下を入力します。
リモートの名前:origin
(なんでも良いのですか初めて設定する時はoriginが慣例となっています。)
URL/パス:GitHubでコピーしたURLを入力します。
ユーザー名:GitHubに登録しているユーザー名を入力します。


リモートタブにURLが追加されます。
→「OK」を押して設定完了です。


3.2.3 .gitignoreファイルの取り込み

現在の情報を整理します。
ローカルリポジトリには、Unityプロジェクトの情報があり、
リモートリポジトリには、「.gitignore」の設定ファイルがある状況です。

ローカルリポジトリにリモートリポジトリの「.gitignore」ファイルを
取り込んで管理対象を限定します。


画面上部の「プル」を押します。


「プルするリモートのブランチ」を「main」に設定して「OK」を押します。
 注1)アカウントが登録(アクセストークン登録)がされていないと
  「main」が選択できないため注意してください。
 注2) アカウント登録済みの場合は「更新」ボタンを押すと
    選択できるようになります。


処理が終わると管理対象が限定されます。
今回の場合、コミットの上の数字を見ると28となっていました。
元々12076と書いてあったため、管理対象が大幅に減ったことがわかります。


初期状態を記録(コミット)

余計なファイルを管理の対象外とすることができたため
ここからローカルリポジトリに対してUnityプロジェクトの初期状態を記録します。


左上のチェックボックスをチェックし、全てのファイルを対象とします。


画面下部のコミットメッセージ欄をクリックします。


変更内容についてのコメントを入力します。
今回は「初期プロジェクト」と入力しました。
コメント入力後「コミット」ボタンを押します。


確認ウインドウが出るので「OK」を押します。


コミットが完了するとファイルの表示が消え、
「コミット対象がありません」と表示されます。


左側の「履歴」を確認するとコミットした内容が確認できます。
「master」と「origin/main」が青枠で表示されていると思います。
「master」はローカルリポジトリを示しており、
「origin/main」はGitHubのリモートリポジトリを示しています。


GitHubへアップロード(プッシュ)

ローカルのプロジェクト内容をGitHubへアップロード(プッシュ)していきます。


画面上部の「プッシュ」を押します。


ローカルのプロジェクト内容である「master」を選択して「OK」を押します。


処理が完了すると「master」と「origin/master」が横並びになります。

急に「origin/master」が出現しましたが、
こちらはoriginというリモートリポジトリのmasterブランチというみたいです。

「origin/master」と「origin/main」の違いをChatGPTさんに質問した結果は以下です。

origin/master:
以前のGitリポジトリでデフォルトブランチとして一般的に使われていたブランチ名です。

origin/main:
新しいGitリポジトリや、デフォルトブランチ名を変更したリポジトリ
使用されるブランチ名です。GitHubを含むいくつかのサービスでは、
master ブランチの名前を main に変更しています。

どうやらGitHubで作成した際はmainという名前の世界で作ったけど
SourceTree上ではmasterという名前の世界で作っているため
GitHub上ではmainとmasterの2つの世界が存在することになるようです。

GitHub上で確認するとmainとmasterが選択できるようになっています。


mainはGitHub上で作成した初期状態のままですが、

masterの方は、SourceTreeからプッシュした内容が反映されています。


デフォルト表示のブランチを切り替える方法(追記)

GitHubのページに行った時に毎回masterブランチへ切り替えるのは面倒なため
デフォルトのブランチを切り替える方法をです。


Settingsを開きます。


Default branch欄の矢印ボタンを押します。

デフォルト設定にしたいブランチ名を選択し「Update」を押します。


以下の警告文が出ます。
更新ボタンを押します。

Changing your default branch can have unintended consequences that can affect new pull requests and clones.
訳)新しいプル リクエストやクローンに影響を与える、意図しない結果が生じる可能性があります。

これでデフォルトのブランチを変更できました。


ブランチ名はDefault branch欄の鉛筆ボタンで変更できるようなので
最初からmain→masterへ切り替えておけば
デフォルトのブランチ名切り替えをしなくても良さそうです。(未検証)

Q&A

Q1:SourceTreeを開いたままUnityを開いても良い?
A1:開いているだけなら問題ない

Q2:Unityを開いたままSourceTreeで操作しても良い?
A2:やめたほうがいい。正しく保存されるかわからない。

Q3:プロジェクトのフォルダにはリリース用のスクショなどを入れておいてもいい?
A3:やめた方がいい。何も設定しないとプロジェクトフォルダ毎で追跡の対象となる。
  そのため、.gitignoreの設定で無視する対象に含めないといけなくなる。
  よって別フォルダで管理した方が楽。

初期設定後の基本操作

初期設定後の基本操作について書いた記事です。 marumaro7.hatenablog.com

本書きました

marumaro7.hatenablog.com

参考

blog.naichilab.com

www.sejuku.net

syslog.life

www.publickey1.jp

【Unity】GDPR対応 UMPを使用し同意フォームを表示する方法 Android iOS

仕様

Unityバージョン:2021.3.27f1
GoogleMobileAds-v8.5.3

前提

・GoogleMobileAdsをプロジェクトに導入済みであること
・広告が表示できる状態であること

はじめに

AdMobの管理画面にこんなメッセージが出てきました。

欧州にもアプリを出していきたいのでGDPR対応をしていきます。
GDPRについての説明は省略します。

警告文にいろいろ書いてありますが
どこかの会社の同意管理プラットフォームと契約してユーザーの同意を得るか
Googleが用意した同意管理の様式でユーザーの同意を得るかという理解をしました。

下記の文にあるUMP(User Messaging Platform) SDK
使用して対応していけばよさそうです。
このUMP SDKはGoogleMobileAdsに含まれています。

Google の同意管理ソリューションに関心をお持ちの場合は、まず GDPR メッセージを設定し、 UMP SDK を実装してください


User Messaging Platform(UMP)SDK設定のページはこちら

https://developers.google.com/admob/unity/privacy?hl=jadevelopers.google.com

注)法律の専門家ではありませんので自己責任にて欧州へのアプリリリースをお願いします。

手順1. 同意依頼メッセージの作成

→AdMob管理画面の「プライバシーとメッセージ」


GDPRの歯車をクリック


→メッセージ
GDPRメッセージを作成


以下の画面になるので各項目を入力します。


アプリの選択の他は以下のように設定しました。


次に進むとユーザーに表示する同意画面のプレビューになります。
以下の設定にして公開しました。
アプリ:対象のアプリが選択されていることを確認
言語:デフォルトの言語は英語に設定
別の言語:すべての言語にチェック

手順2.アプリ計測の遅延設定

ここからUnity上での設定になります。

ユーザーの同意が得られるまでユーザーの計測ができないため
Mobile Ads SDK を初期化するか広告を読み込むまで、
アプリの測定を明示的に遅らせる必要があります。

設定は簡単で以下の手順で設定ウインドウ表示してから
→アセット
Google Mobile Ads]
→Settings


同意メッセージのDelay app measurementを有効にします。

手順3.デバイスIDの取得

テストで同意フォームを表示するためには、
手持ちの端末が欧州経済領域(EEA)に存在していると設定する必要があります。
その設定のためには、デバイスのIDが必要ですので最初にデバイスIDを取得してしまいます。
(ここでいうデバイスIDは広告のテストデバイスIDとはまた別の文字列になります。)


端末側での関数の実行結果を確認する必要があるため
下記のコードをアプリ側で実行してください。

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

public class GDPR : MonoBehaviour
{
    void Start()
    {
        //デバッグ用に端末のID取得
        //================================================================
        // 端末固有のIDを取得
        string deviceID = SystemInfo.deviceUniqueIdentifier;

        // 取得したIDを全て大文字に変換(大文字にしないとデバッグができません)
        string deviceIDUpperCase = deviceID.ToUpper();

        // 端末IDの表示
        Debug.Log("TestDeviceHashedId = " + deviceIDUpperCase);
        //================================================================
    }

}


iOSではXcodeから実機テストすると実機ログを確認できます。
例:4C70843B-1592-427A-831F-D72A3298AD5D


Androidではログ確認はできないため、Android Logcatを導入し確認可能にします。
(パッケージを入れるだけなのでとても簡単です。)
marumaro7.hatenablog.com

Android Logcatの検索窓に
TestDeviceHashedId
と打ち込むとデバイスIDが表示されるはずです。
例:F8026D2238D034DD0896BF099FAAD9CC
取得したデバイスIDはメモしておいてください。

手順4.スクリプト作成

スクリプトは次の3ステップで完成となります。
1.基本スクリプトの作成
2.デバイスIDの設定
3.広告読み込みの設定

4-1.基本スクリプトの作成

以下のスクリプトを作成し、空のゲームオブジェクトに割り当てます。
スクリプトの詳しい内容はコメントをご確認ください。

using System.Collections;
using System.Collections.Generic;
using GoogleMobileAds.Api;
using GoogleMobileAds.Ump.Api;
using UnityEngine;

public class GDPR : MonoBehaviour
{
    //広告読み込み開始用
    //広告のスクリプトをインスペクター上でそれぞれ割り付けてください
    //以下は例です。
    //==============================================================
    [SerializeField] private AdMobBanner adMobBanner;
    [SerializeField] private AdMobInterstitial adMobInterstitial;
    [SerializeField] private AdMobReward adMobReward;
    //==============================================================

    private void Start()
    {
        //デバッグ用に端末のID取得
        //================================================================
        // 端末固有のIDを取得
        string deviceID = SystemInfo.deviceUniqueIdentifier;

        // 取得したIDを全て大文字に変換(大文字で登録しないと同意フォームが表示されませんでした)
        string deviceIDUpperCase = deviceID.ToUpper();

        // 端末IDの表示
        Debug.Log("TestDeviceHashedId = " + deviceIDUpperCase);
        //================================================================


        //同意フォームのリクエスト作成
        ConsentRequestParameters request = new ConsentRequestParameters
        {
            // 未成年者の同意に関するタグを設定します。
            // falseはユーザーが未成年者でないことを意味します。
            TagForUnderAgeOfConsent = false,


            //同意フォームテスト用
            //==========================================================================
            //GDPRの対象地域で起動したことにする設定            
            ConsentDebugSettings = new ConsentDebugSettings
            {
                DebugGeography = DebugGeography.EEA,
                TestDeviceHashedIds = new List<string>
                {
                    //同意フォームを表示する端末のデバイスIDを入力
                    //Android 例
                    "F8026D2238D034DD0896BF099FAAD9CC",                    
                    
                    //iOS 例
                    "4C70843B-1592-427A-831F-D72A3298AD5D"
                }
            }
            //==========================================================================            
        };

        // 同意情報の更新をリクエスト
        ConsentInformation.Update(request, OnConsentInfoUpdated);        
    }

    //同意情報の更新後に実行する関数
    private void OnConsentInfoUpdated(FormError consentError)
    {
        if (consentError != null)
        {
            Debug.Log("error consentError = " + consentError);
            return;
        }

        //ユーザーの同意が必要でまだ得られていない場合に、同意フォームをロードして表示します。
        ConsentForm.LoadAndShowConsentFormIfRequired((FormError formError) =>
        {
            //同意が得られなかった時の処理
            if (formError != null)
            {
                Debug.Log("error consentError = " + consentError);
                return;
            }


            //同意ステータス確認
            //https://developers.google.com/admob/unity/reference/namespace/google-mobile-ads/ump/api#namespace_google_mobile_ads_1_1_ump_1_1_api_1aa83ad2ecf6f2a08c584b60cef06f5133
            //NotRequired:同意は必要ありません。CanRequestAds()はtrueとなります。
            //Obtained:ユーザーの同意が得られました。パーソナライズされたものとパーソナライズされていないものは未定義です。
            //Required:ユーザーの同意が必要ですが、まだ取得されていません。
            //Unknown:不明な同意状況。同意状況が確認とれるまではUnkownが表示されます。
            Debug.Log("ConsentStatus = " + ConsentInformation.ConsentStatus.ToString());

            //CanRequestAds()の値確認用
            Debug.Log("CanRequestAds = " + ConsentInformation.CanRequestAds());

            // ここまで処理が進んでいれば同意が得られたことになる
            if (ConsentInformation.CanRequestAds())
            {
                //https://developers.google.com/admob/unity/quick-start?hl=ja
                // true の場合、GoogleMobileAds によって発生するすべてのイベントが発生します
                // Unity メインスレッド上で。 デフォルト値は false です。
                MobileAds.RaiseAdEventsOnUnityMainThread = true;
                 
                //広告の初期化完了後 広告読み込み開始
                MobileAds.Initialize((InitializationStatus initstatus) =>
                {
                    //広告のスクリプト側で設定している広告を読み込む関数をここで実行してください。
                    //広告読み込み開始
                    //以下は例です。
                    //===========================
                    adMobBanner.AdStart();
                    adMobInterstitial.AdStart();
                    adMobReward.AdStart();
                    //===========================
                });
                
            }
        });
    }



    //同意フォームの再表示用
    public void LoadAndShowConsentForm()
    {
        Debug.Log("LoadAndShowConsentForm Start!");

        // 同意フォームをロードします
        ConsentForm.Load((consentForm, loadError) =>
        {
            if (loadError != null)
            {
                Debug.Log("error loadError = " + loadError);
                return;
            }

            // 同意フォームがロードされました
            // フォームを表示します
            consentForm.Show(showError =>
            {
                if (showError != null)
                {
                    Debug.Log("error showError = " + showError);
                    return;
                }
            });
        });
    }


    //GDPRデバッグテスト用 同意情報リセット
    public void GDPRReset()
    {
        Debug.Log("Reset Start!");
        ConsentInformation.Reset();
    }


}



以下、同意フォーム再表示用のLoadAndShowConsentForm()関数と、
同意情報リセットGDPRReset()関数はテストを円滑に実施するために書いています。
不要であれば削除していただいて問題ありません。

同意フォーム再表示用 LoadAndShowConsentForm()関数

    //同意フォームの再表示用
    public void LoadAndShowConsentForm()
    {
        Debug.Log("LoadAndShowConsentForm Start!");

        // 同意フォームをロードします
        ConsentForm.Load((consentForm, loadError) =>
        {
            if (loadError != null)
            {
                Debug.Log("error loadError = " + loadError);
                return;
            }

            // 同意フォームがロードされました
            // フォームを表示します
            consentForm.Show(showError =>
            {
                if (showError != null)
                {
                    Debug.Log("error showError = " + showError);
                    return;
                }
            });
        });
    }


同意情報リセット GDPRReset()関数

    //GDPRデバッグテスト用 同意情報リセット
    public void GDPRReset()
    {
        Debug.Log("Reset Start!");
        ConsentInformation.Reset();
    }

4-2.デバイスIDの設定

下記の部分のデバイスIDを先ほど取得したデバイスIDに差し替えてください。

            //同意フォームテスト用
            //==========================================================================
            //GDPRの対象地域で起動したことにする設定            
            ConsentDebugSettings = new ConsentDebugSettings
            {
                DebugGeography = DebugGeography.EEA,
                TestDeviceHashedIds = new List<string>
                {
                    //同意フォームを表示する端末のデバイスIDを入力
                    //Android 例
                    "F8026D2238D034DD0896BF099FAAD9CC",                    
                    
                    //iOS 例
                    "4C70843B-1592-427A-831F-D72A3298AD5D"
                }
            }
            //========================================================================== 

4-3.広告読み込みの設定

以下の2箇所は私が使用している広告スクリプト名、関数名のため
エラーが発生していると思います。
ご自身のプロジェクトで使用される広告読み込み関数に差し替えてください。

    //広告読み込み開始用
    //広告のスクリプトをインスペクター上でそれぞれ割り付けてください
    //以下は例です。
    //==============================================================
    [SerializeField] private AdMobBanner adMobBanner;
    [SerializeField] private AdMobInterstitial adMobInterstitial;
    [SerializeField] private AdMobReward adMobReward;
    //==============================================================
                //広告の初期化完了後 広告読み込み開始
                MobileAds.Initialize((InitializationStatus initstatus) =>
                {
                    //広告のスクリプト側で設定している広告を読み込む関数をここで実行してください。
                    //広告読み込み開始
                    //以下は例です。
                    //===========================
                    adMobBanner.AdStart();
                    adMobInterstitial.AdStart();
                    adMobReward.AdStart();
                    //===========================
                });

実機確認

実機で起動すると以下のウインドウが表示されるはずです。
※正しいデバイスIDが登録されていないと表示されません。

実装方法は以上です。

広告表示の確認

ここからは同意フォームの入力結果による広告表示のメモとなります。(Android端末で実施)

・「同意」ボタン押下後
問題なし 広告表示される


・「オプションを管理」→「すべて承認」押下後
問題なし 広告表示される

 → 


・「オプションを管理」→「選択を確定」押下後
問題あり 広告が表示されない(詳細設定の内容全てを有効にしても表示されない)

 → 


・「オプションを管理」→「選択を確定」押下後 → フォームを再表示して同意
難あり 再起動すると広告が表示される

詳細
1.「オプションを管理」→「選択を確定」押下後 広告が表示されない状態から
 →   

2.同意フォームを再表示して同意
この状態で同意しても広告は表示されないがアプリを再起動すると広告は表示される


結論、「オプションを管理」→「選択を確定」と押された場合広告が表示されなくなります。
UMP SDKが用意してくれた広告表示可否を判断するための
ConsentInformation.CanRequestAds()
の値はtrueであるためUMP SDKとしては広告が出せると判定されているが
実際は広告を出せないということになります。


これは下記でで2020年から議論されているようですが未だ解決していません。
(Safariで開くとメッセージが省略されるため、
 それぞれのスレッドをクリックして展開する必要があります。)
groups.google.com



それで、どうする??
についてですが、現在、対処法は確定していません。
テストしていったところ、同意状態を示すConsentStatusがObtained(同意)
となった時が同意フォームが表示され、いずれかのボタンが押されたということになるため、

「ConsentStatusがObtained(同意)」かつ「広告のロードが失敗する」

この2つの条件が揃った場合に以下のようなテキストを表示して
同意フォームの同意を促すしかないのかなと考えています。
「同意フォームの同意がなければ広告が発生せず報酬の受け取りができません。
 次のフォームに同意してアプリを再起動してください」


ちなみに、
日本にいてデバイスIDを設定していない時はEEA対象外の地域となるため
同意フォームは表示されずに広告の読み込みは開始されます。
※同意状態を示すConsentStatusはNotRequired(同意の必要なし)となります。

おわりに

広告が出ない状況に対しての最適解がない状態ですが
同意フォームを表示する目的は果たせたので一歩前進です。

残りの未確定ポイントは、iOSのATTリクエストウインドウは
GDPR同意フォームの後に表示することで問題ないのかという点です。

こちらはiOSの審査に出すまでわからないため広告表示問題と併せて
情報がありましたら教えていただけると嬉しいです。

本記事からなにか得るものがありましたら幸いです。ではでは。

プログラム入門本 書きました

marumaro7.hatenablog.com

参考

・参考動画

www.youtube.com


・リファレンス

developers.google.com

developers.google.com


・確認した情報 www.reddit.com

Androidパーソナライズされていない広告を出す方法らしい itnext.io