UnityでAdmob実装とストアへのリリースなど

[【完走したい】楽しくいろいろやる Advent Calendar 2023](https://qiita.com/advent-calendar/2023/notbeginner)7日目の記事です。
広告のつけ方とかリリースの仕方など学びました。


少しずつアプリを作っていましたが、途中で
![スクリーンショット 2023-10-18 002502.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2961125/a47ce03c-e78c-ad45-00d5-0b8fffa9a16a.png)
これが出て、直せずに新しく作り直していたら時間がかかりすぎて
![スクリーンショット 2023-09-18 140853.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2961125/6765f7b9-7bab-bada-d094-98414fc0d71a.png)

こうなりました。
ということで、さっさとアプリをリリースします。
# 下準備
せっかくなのでAdmobのつけ方も簡単に説明します。
・[Google Admob](https://admob.google.com/intl/ja/home/get-started/?subid=jp-ja-ha-z-g-a-de!o3~17547741502~141599849881~admob~e&utm_source=sem&utm_medium=text&utm_campaign=2023q3admob_apac_jp&utm_content=rsa&gclid=Cj0KCQjwx5qoBhDyARIsAPbMagALz8TtRKcv0Vq3id7EuEV6WZkvZDfQ7aJY384SV-iO7lKiPq9d-QMaAlSzEALw_wcB&gclsrc=aw.ds)
アカウントを作りましょう。
次に、Unityに色々入れます。（急ぎで書いてるので端折ります。調べれば出ます)
テスト用のIDを入れてちゃんとテスト広告が出るとか、テスト端末でちゃんと動くかとかよく調べたらOKです。
![スクリーンショット 2023-09-18 141821.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2961125/7f0f9f6e-230f-60dd-a049-f8fca297221a.png)
こんな感じです。
ちなみに、私は広告をつけるまでに3か月くらいかかりました。（androidmanifest.xmlの設定がうまくいってなかったため）
広告をつける際に、数字が/で区切られているタイプのものと~で区切られているものの２種類存在すると思います。使いかたを書いておきます。私はなぜ２つあるのかわからず１日かかってしまいました。
/で区切られているものは、広告を表示するための下にある実装したコードで使いました。
~で区切られているものはAndroidManifest.xmlで使います。
![スクリーンショット 2023-11-18 004710.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2961125/a18c852f-1c9f-f51f-8085-6c22d92cad21.png)
これには~のほうを使いましょう。

---
広告をつけるまではここで終わりです。次に、ゲームを制作後からリリースまでの過程を書いておきます。

大前提として、Android用にGooglePlayにアプリをリリースするためにはGooglePlayConsoleへの登録が必須でした。
・[GooglePlayConsole](https://developer.android.com/distribute/console?hl=ja)
25ドルあれば簡単にアカウントを作れました。
本人確認などを済ませたら画面に従って色々やって、アプリをリリースすればOKみたいです。
プライバシーポリシーとかを作る際は、わざわざサイトを作らなくてもGoogleドキュメントとかでOKみたいです。無料だし簡単です。


### 審査について
アプリ初リリース時、審査に6日間かかりました。
気長に待ちましょう。


# 詰まったポイント
広告実装
[公式](https://developers.google.com/admob/unity/rewarded?hl=ja#android)を元に実装してみたコード↓
```
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using GoogleMobileAds;
using GoogleMobileAds.Api;
using System;
//using UnityEditor.PackageManager.Requests;

public class AdsRewardNew1 : MonoBehaviour
{
    public GameObject Twall;
    public GameObject AdsReadyF;
    public NewMain NewMain;
    public SoundBtn SoundBtn;
    public GameObject AdsFailed;
    public GameObject Hantei;

#if UNITY_ANDROID
    private string _adUnitId = "ca-app-pub-xxxxxxxxxxxxxxxx/xxxxxxxxxx";
#elif UNITY_IPHONE
  private string _adUnitId = "ca-app-pub-xxxxxxxxxxxxxxxx/xxxxxxxxxx";
#else
  private string _adUnitId = "unused";
#endif

    private RewardedAd _rewardedAd;
    // Start is called before the first frame update
    void Start()
    {
        AdsFailed.SetActive(false);
       
    }
    // These ad units are configured to always serve test ads.


    /// <summary>
    /// Loads the rewarded ad.

    /// </summary>
    public void OnClick()
    {
        // this.gameObject.transform.position = new Vector3(100, 100, 100);
        
        SoundBtn.SoundA = false;
        AdsReadyF.SetActive(true);
        Twall.SetActive(true);
        LoadRewardedAd();
    }
    public void LoadRewardedAd()
    {
        // Clean up the old ad before loading a new one.
        if (_rewardedAd != null)
        {
           
            _rewardedAd.Destroy();
            _rewardedAd = null;
        }

        Debug.Log("Loading the rewarded ad.");

        // create our request used to load the ad.
        var adRequest = new AdRequest();

        // send the request to load the ad.
        RewardedAd.Load(_adUnitId, adRequest,
            (RewardedAd ad, LoadAdError error) =>
            {
                // if error is not null, the load request failed.
                if (error != null || ad == null)
                {
                    AdsFailed.SetActive(true);
                    Hantei.SetActive(true);
                    SoundBtn.SoundA = true;
                    this.gameObject.transform.position = new Vector3(0, -4, 40);
                    AdsReadyF.SetActive(false);
                    Twall.SetActive(false);
                  //  this.gameObject.SetActive(false);
                    Debug.LogError("Rewarded ad failed to load an ad " +
                                   "with error : " + error);
                    return;
                }

                Debug.Log("Rewarded ad loaded with response : "
                          + ad.GetResponseInfo());

                _rewardedAd = ad;
                ShowRewardedAd();
            });
    }
    //reward callback
    //メモ：74行目と76行目の_rewardedAdは元々_が入っていなかった
    public void ShowRewardedAd()
    {
        const string rewardMsg =
            "Rewarded ad rewarded the user. Type: {0}, amount: {1}.";

        if (_rewardedAd != null && _rewardedAd.CanShowAd())
        {
            _rewardedAd.Show((Reward reward) =>
            {
                AdsFailed.SetActive(false);
                Hantei.SetActive(false);

                SoundBtn.SoundA = true;
                this.gameObject.transform.position = new Vector3(0, -4, 40);
                AdsReadyF.SetActive(false);
                Twall.SetActive(false);
                // TODO: Reward the user.
                NewMain.AdsRewardAct();
                Debug.Log(String.Format(rewardMsg, reward.Type, reward.Amount));
            });
        }
    }
    //125行目の ad.OnAdFullScreenContentClosed += ()=>はもともと=>が入っていなかった
    private void RegisterEventHandlers(RewardedAd ad)
    {
        // Raised when the ad is estimated to have earned money.
        ad.OnAdPaid += (AdValue adValue) =>
        {
            Debug.Log(String.Format("Rewarded ad paid {0} {1}.",
                adValue.Value,
                adValue.CurrencyCode));
        };
        // Raised when an impression is recorded for an ad.
        ad.OnAdImpressionRecorded += () =>
        {
            Debug.Log("Rewarded ad recorded an impression.");
        };
        // Raised when a click is recorded for an ad.
        ad.OnAdClicked += () =>
        {
            Debug.Log("Rewarded ad was clicked.");
        };
        // Raised when an ad opened full screen content.
        ad.OnAdFullScreenContentOpened += () =>
        {
            Debug.Log("Rewarded ad full screen content opened.");
        };
        // Raised when the ad closed full screen content.
        ad.OnAdFullScreenContentClosed += () =>
        {
           
            Debug.Log("Rewarded ad full screen content closed.");
            _rewardedAd.Destroy();
          
        };
        // Raised when the ad failed to open full screen content.
        ad.OnAdFullScreenContentFailed += (AdError error) =>
        {
            Debug.LogError("Rewarded ad failed to open full screen content " +
                           "with error : " + error);
        };
    }
    
        private void RegisterReloadHandler(RewardedAd ad)
    {
        // Raised when the ad closed full screen content.
        ad.OnAdFullScreenContentClosed += ()=>
    {
            Debug.Log("Rewarded Ad full screen content closed.");

            // Reload the ad so that we can show another as soon as possible.
            LoadRewardedAd();
        };
        // Raised when the ad failed to open full screen content.
        ad.OnAdFullScreenContentFailed += (AdError error) =>
        {
            Debug.LogError("Rewarded ad failed to open full screen content " +
                           "with error : " + error);

            // Reload the ad so that we can show another as soon as possible.
            LoadRewardedAd();
        };
    }
    // Update is called once per frame
   
}
```
「//」でコメントアウトした部分（日本語で書いてあるもの）に、変更した部分（間違ってると思われる部分）を記載しています。
手を加えていない状態（[公式](https://developers.google.com/admob/unity/rewarded?hl=ja)のものを上から順番に書き写したもの）では以下のようなエラーが出ました。

![スクリーンショット 2023-11-18 002051.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2961125/ee48e78b-a589-709c-fe3c-5829e24e7780.png)

見切れてますが、５個のエラーが出ています。

# 本日学んだこと　アニメーションの管理
おそらく初めて学んだこと
・アニメーションの管理
アニメーションは
```
 public Animator Animator;
```
とか書いて、
```
 Animator.speed = 0;
```
とかでスピード調節できます。
初期化するには
```
WinChest1.SetActive(false);
WinChest1.SetActive(true);
Animator.Play("idle");
Animator.speed=0;
```
とかでいけます。何故かいったんオブジェクトを非表示→表示を行わないと、ちゃんと初期化されませんでした。
スピードは、初期化後に0にしておくと、初期化された状態で止まってくれます。

・BGMのつけ方
ゲームを作るにあたり音楽をつけようと考えました。簡単にできました。
```
 public AudioClip BGMA;
    public AudioClip BGMB;
```
AudioClipでBGMをくっつけて、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2961125/ea578539-a7ed-95d3-3b36-a65b7651d52a.png)
```
AudioSource.PlayOneShot(BGM名);
```
こんなもんで簡単に行けました
止めるときもStop()とかで適当に止めとけばいいと思います。

# まとめ
初心者でも時間とやる気があればゲームはリリースできる。