そういうのがいいブログ

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

アプリ開発覚え書き

【Unity】AdMobのUnityAdsメディエーションでiOSリリース直後から広告を表示する 

前提

AdMobの広告を実装できている方向け
GoogleMobileAds-v5.4.0
GoogleMobileAdsUnityAdsMediation-2.5.1

はじめに

AdMobの広告を使用する上で、
iOS版は2020年11月頃からアプリリンクしないと広告が表示されなくなりました。
この影響でAppleの審査が落ちるという事態も発生しているようです。

このAppleの審査を通す対策として、2つの方法があります。

①「広告無しで審査を通す→AdMob上でアプリリンクする→広告実装する」
 メリット
  簡単
 デメリット
 ・再審査が面倒
 ・広告前提の構成の場合、審査のためにアプリの構成を調整する必要がある
 ・アプリリンク5日以上かかるため、もやもやする


AdMobメディエーションを使用しAdMob以外の広告ソースから広告を表示する
 メリット
 ・メディエーションを使用することで、単価が高い広告が表示されるようになる。
 ・リリース直後からiOS版でも広告表示が可能になる。
 デメリット
  ①の方法より手間がかかる

今回はタイトルにもあるように
②の方法(広告ソースはUnityAdsを使用)で
iOSリリース直後から広告を表示できるようにします。
この記事では、私がメディエーション設定を実装した際の
"つまづいたこと"を中心に書いていきます!

<追記>
Unityのダッシュボードの構成が変わっていたので、
つまづいたところを中心に書きました。
marumaro7.hatenablog.com

前準備

メディエーション設定をするうえで、8割は公式の説明書を順に追っていくだけでいけました。

説明書
Unity広告とメディエーションの統合  |  Google Developers

ただ、英語で書いてあるので英語ができない私には非常に読みにくかったです。
そこで、Chromeのページ全体を翻訳機能を使って読み進めました。

Chrome拡張機能実装手順
ChromeでGoogle翻訳の拡張機能を使おう。英語サイトも怖くないぞ!

つまづいたポイント

1.eCPMいくらでいれたらいいかわからない問題

説明書の項目<UnityAdsを広告ソースとして追加する>のところで

eCPMを自動で調整する設定にしていても、最初は入力する必要があります。
youtubeで調べたら2ドルで入れていたので、真似して2ドルで設定しました。
(よくわかってない)
f:id:marumaro7:20210116162312p:plain:w300

2.xmlファイル編集方法わからない問題

説明書のこちらの内容は次の方法で設定します。 f:id:marumaro7:20210116163817p:plain

説明書に書いてある通り、こちらのファイルを開きます。
Assets/GoogleMobileAds/Editor/UnityMediationDependencies.xml f:id:marumaro7:20210116164230p:plain:w400

開くとこちらのようになっていると思います。

<dependencies>
  <androidPackages>

   <androidPackage spec="com.google.ads.mediation:unity:3.5.1.1">
      <repositories>
        <repository>https://jcenter.bintray.com/</repository>
      </repositories>
    </androidPackage>

    <!-- If using the Unity Ads Service from Unity3D, use this dependency instead to exclude the
    Unity Ads SDK and avoid conflicting dependency issues. -->
    <!--
   <androidPackage spec="com.google.ads.mediation:unity-adapter-only:3.5.1.1">
      <repositories>
        <repository>https://jcenter.bintray.com/</repository>
        <repository>https://google.bintray.com/mobile-ads-adapters-android</repository>
      </repositories>
      </androidPackage>
    -->

  </androidPackages>

  <iosPods>
    <iosPod name="GoogleMobileAdsMediationUnity" version="3.5.1.1">
      <sources>
        <source>https://github.com/CocoaPods/Specs</source>
      </sources>
    </iosPod>
  </iosPods>
</dependencies>

次のように変更します。

<dependencies>
  <androidPackages>
  
        <!--ここから
    <androidPackage spec="com.google.ads.mediation:unity:3.5.1.1">
      <repositories>
        <repository>https://jcenter.bintray.com/</repository>
      </repositories>
    </androidPackage>
        ここまで無効-->
        
        
    <!-- If using the Unity Ads Service from Unity3D, use this dependency instead to exclude the
    Unity Ads SDK and avoid conflicting dependency issues. -->
    <!--ここから-->
    <androidPackage spec="com.google.ads.mediation:unity-adapter-only:3.5.1.1">
      <repositories>
        <repository>https://jcenter.bintray.com/</repository>
        <repository>https://google.bintray.com/mobile-ads-adapters-android</repository>
      </repositories>
    </androidPackage>
    <!--ここまで有効-->

  </androidPackages>

  <iosPods>
    <iosPod name="GoogleMobileAdsMediationUnity" version="3.5.1.1">
      <sources>
        <source>https://github.com/CocoaPods/Specs</source>
      </sources>
    </iosPod>
  </iosPods>
</dependencies>

やっていることは
xmlコメントアウトコメントアウトの解除だけです。

 <!--コメントアウトする内容-->

おわりに

xmlの編集方法を調べる良い機会になりました。

最近「ダンスドリームMV」というダンスアプリをリリースしました。
もしこの記事が役に立ったら、このアプリの⭐️5評価お願いします!(懇願)
iOS
http://urx3.nu/QvFa
Android
http://urx3.nu/iRcv

Twitter
twitter.com

【Unity】returnに"?" 条件演算子とは

returnに"?"マークあるんですけど????

ブログを見ていたら

returnに"?"が書いてあって、内容が理解できなかったのでメモ

正体は条件演算子

結論として条件演算子というみたいで、
こちらの情報で解決しました。
"?"と":" のセットで使うみたいですね。

組込み演算子 - C# によるプログラミング入門 | ++C++; // 未確認飛行 C f:id:marumaro7:20201227093504p:plain

具体例

あとから見たときにまたわからなくなりそうなので、 具体例書いておきます。

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

public class Test : MonoBehaviour
{
    private string a;//string型の変数aを宣言
    private bool c;//bool型の変数cを宣言

    private string b;//string型の変数bを宣言

    void Start()
    {
        a = "あ";//変数aに文字列 あ を代入

        b=AAA();//関数AAA()を実行し、その返り値を変数bに代入

        Debug.Log(b);//コンソールに変数bの文字列を表示
    }      


    //返り値の型がstring型の関数AAAを作成
    private string AAA()
    {
        if (a == "あ")
        {
            c = true;//aの文字列が あ だったら変数cをtrueにする
        }
        else
        {
            c = false;//aの文字列が あ ではなかったら変数cをfalseにする
        }

        //cがtrueなら返り値は "変数aには あ が入っています。" になる
        //cがfalseなら返り値は "変数aには あ は入っていません。" になる
        return c ? "変数aには あ が入っています。" : "変数aには あ は入っていません。";
    }    
}



このスクリプトを"空のオブジェクト"にセットして
f:id:marumaro7:20201227094342p:plain:w400



実行すると 関数AAA()の返り値の値は
「"変数aには あ が入っています。"」
が返ってきていることがわかります。
f:id:marumaro7:20201227094445p:plain:w400

おわりに

return A ? B : C
のBとCには"返り値のある関数"を入れることもできるようです。

私が初めてみたのは関数が入っていたので、大混乱でしたー!!

【Unity】iOSアプリ申請 却下理由と対策 メモ

f:id:marumaro7:20201220085819p:plain

iOSのアプリ却下理由と対策をメモとして残していきます。
※まだ対策していない内容も含まれます。

1.Guideline 3.1.1 - Business - Payments - In-App Purchase

f:id:marumaro7:20201220083739p:plain

題名

0.1.9 バイナリでの却下 2020年12月18日 AppReview Guideline 3.1.1 - Business - Payments - In-App Purchase Your app uses intermediary currency to purchase items that function as

訳:AppReview ガイドライン3.1.1-ビジネス-支払い-アプリ内購入アプリは、中間通貨を使用して、次のように機能するアイテムを購入します。

本文

Guideline 3.1.1 - Business - Payments - In-App Purchase

Your app uses intermediary currency to purchase items that function as non-consumable products but does not include a restore mechanism.

Users restore transactions to maintain access to content that they've already purchased.

Next Steps

To resolve this issue, please modify your app to include an optional user-registration feature that allows users to restore their purchases to all of their iOS devices.

We recommend indicating that account registration is necessary to restore previously purchased in-app purchase products and providing a way for users to register later if they wish to access this content in the future.

Please see attached screenshot for details.

訳:ガイドライン3.1.1-ビジネス-支払い-アプリ内購入

アプリは中間通貨を使用して、非消耗品として機能するアイテムを購入しますが、復元メカニズムは含まれていません。

ユーザーはトランザクションを復元して、購入済みのコンテンツへのアクセスを維持します。

次のステップ

この問題を解決するには、アプリを変更して、ユーザーが購入したものをすべてのiOSバイスに復元できるオプションのユーザー登録機能を含めるようにしてください。

以前に購入したアプリ内購入商品を復元するにはアカウント登録が必要であることを示し、ユーザーが将来このコンテンツにアクセスしたい場合に後で登録する方法を提供することをお勧めします。

詳細については、添付のスクリーンショットを参照してください。

添付のスクリーンショット
f:id:marumaro7:20201220084415p:plain

内容解釈

今回のアプリではコイン(無課金で取得可)を使用し、
アプリ内のショップで買い切りのアイテムを販売しています。

この買い切りアイテムの購入データは端末に保存していますが、
それだけではダメで、購入データとユーザーを特定できる仕組みを
用意しないといけないということでしょうか?
ユーザー登録の仕組みって難しくないですか(汗)

とりあえずダメ元で問い合わせ

お世話になります。
審査ありがとうございます。

ご指摘の無課金で購入できる買い切りアイテムについて、

こちらの購入データはアンインストール後、
再インストールしても端末のデータから情報が復元されるのですが、
この設計では問題があるということなのでしょうか?

お忙しいところ恐れ入りますが、ご回答よろしくお願い致します。

Apple返信

Hello,

Thank you for providing this information.

Regarding 3.1.1, we found that your app allows the user to unlock non-consumable items such as characters, using an intermediary currency, but does not include a restore mechanism.

To resolve this issue, please modify your app to include an optional user-registration feature that allows users to restore their purchases to all of their iOS devices.

We look forward to reviewing your resubmitted app.

Best regards,

App Store Review

訳:こんにちは、

この情報を提供していただきありがとうございます。

3.1.1に関しては、アプリでユーザーが中間通貨を使用してキャラクターなどの非消耗品のロックを解除できることがわかりましたが、復元メカニズムは含まれていません。

この問題を解決するには、アプリを変更して、ユーザーが購入したものをすべてのiOSバイスに復元できるオプションのユーザー登録機能を含めるようにしてください。

再送信されたアプリを確認することを楽しみにしています。

宜しくお願いします、

AppStoreレビュー

【Unity】課金設定 Unity IAPにGoogle 公開鍵を設定する

<追記 2021.10.6>
Dashboard上での設定は不要になりました!
(Dashboard上の設定項目自体が消えています・・・)
公開鍵を入れて「Verify」を押せば設定できました。


Unity IAPへのGoogle公開鍵設定ではまったのでメモ

前提条件

Google Play Consoleにapkファイルがアップロードされている
・Unity IAPが有効になっている

1.Google Play Console上で公開鍵の取得

公開鍵の取得

2.Unity IAPで公開鍵を設定する

注意 Unity上からは設定できない

Optionsのところで入力欄がありますが、入力しても無効となってはじかれます。 f:id:marumaro7:20201119051019p:plain:w400

2-1 Unity Analyticsへ移動

Unity IAP画面右上の Go to Dashboardをクリック ダッシュボード

2-2 公開鍵を入力

Settings
→Analytics Settings
Google License Keyに公開鍵を入力
→保存ボタンを押す

公開鍵入力

2-3 Unityへ戻って公開鍵を反映

Unity IAPへ戻って入力欄に公開鍵を入力してVerfyボタンを押す



設定完了!

aa

おわりに

課金設定なにがなんやらわからんですねー。


最後に宣伝させてください。
アプリ開発を始めて丸2年が経ち、
節目としてなにか形にしたいと思い、Udemy講座を出しました!
www.udemy.com

ブログ限定割引リンクは私のプロフィールページにあります。
アプリ開発収益化を時短したい方向けの講座となっております。

参考

develop.hateblo.jp

DanceDreamMV プライバシーポリシー

制定日:2021/1/1

このページは、Maruyu Apps(以下「私」と言います。)が提供するスマートフォンアプリ「DanceDreamMV」(以下「本アプリ」と言います。)における利用者情報の取扱いについて、以下のとおりアプリケーション・プライバシーポリシー(以下「本ポリシー」といいます。)を定め、公表しております。本アプリをインストールする前に本ポリシーをご確認いただき、内容をご理解の上で本アプリをご利用下さい。
なお、本ポリシーにおいて、「利用者情報」とは、お客様の識別に係る情報、通信サービス上の行動履歴、その他お客様のスマートフォンにおいてお客様と結びついた形で生成、利用又は蓄積されている情報であって、本ポリシーに基づき当社が取得するものを意味するものとします。

本アプリが利用する利用者情報

 
本アプリが利用する利用者情報は、下記の3つです。
  • アプリの広告表示のためにお客様の情報の一部を送信する可能性があります。
  • アプリではアクセス解析ツールを用いてアプリの利用状況を収集しております。
  • 問い合わせの際に利用者情報の一部を送信します。
  1. アプリの広告表示本アプリは広告表示のためにお客様の情報の一部を送信する可能性があります。広告表示は、下記2社のサービスを利用しており、本アプリは2社に利用者情報の提供を行います。それぞれのサービスが利用している利用者情報と目的については各社のサービスのプライバシーポリシーをご確認ください。

  2.アプリのアクセス解析
  本アプリではアクセス解析ツールを用いてアプリの利用状況を収集しております。

  アクセス解析Google Analyticsを利用しております。

  本アプリは画面遷移を行った際に、画面IDと利用者情報をGoogle Analytics

  に送付します。

  1. 問い合わせ
    本アプリでは問い合わせの際に利用者情報の一部を送信します。
    問い合わせはメールで行い、メール本文に下記情報が埋め込まれます。また、メールで送信されるため、メールアドレスも送信されます。
    • 名前、メールアドレス
    • 端末名、OSバージョン、その他端末情報(画面サイズ、ピクセル密度、利用可能ヒープメモリ量)
    • アドオン購入状況

利用目的

利用者情報はそれぞれ下記目的に利用されます。

  • 三者の広告の配信・表示のため
  • 当社のサービスに関連して、個人を識別できない形式に加工した統計データを作成するため
  • 本アプリに関するご案内、お問い合せ等への対応のため

【Unity】AndroidとiOSで処理を分ける方法

すぐ見れるようにメモ

公式 docs.unity3d.com

private void Start()
    {
#if UNITY_ANDROID //アンドロイドだったら処理

        //Androidの処理を書く

#endif //アンドロイドの処理範囲終わり


#if UNITY_IOS //iOSだったら処理

        //iOSの処理を書く

#endif //iOSの処理範囲終わり
    }

#if UNITY_IOS
の代わりに #if UNITY_IPHONEでもできるが非推奨なので使用しない!!




おまけ #elseを使ってそれ以外の動作を指定することも可能

#if UNITY_ANDROID
   //Androidの処理
#else
   //Android以外の処理
#endif




<追記>

Application.platformを使っても判別できます。(変数一覧)
こちらは、読めれば良いでしょう。

using UnityEngine;
using System.Collections;

public class Example : MonoBehaviour
 {
    void Start ()
   {
        if (Application.platform == RuntimePlatform.Android)
        {
            //Androidの場合の処理
        }  
        else if (Application.platform == RuntimePlatform.IPhonePlayer) 
        {
            //iOSの場合の処理  (iPadで動作するかは未確認)
        } 
        else
        { 
            //その他の端末での処理
        }
    }
}

【Unity】これでラムダ式への耐性アップ!ラムダ式の記述方法まとめ

はい!今回は勉強した過程を書いていきます!
ラムダ式の存在は知っていましたが、読み方がなにもわからない"まる"です。

サンプルコードが読めないと処理が把握できないので、
重い腰を上げて勉強することにしました。
STEPを踏んで勉強の過程を残していきます。

ラムダ式とは

ざっくりいうと"要点だけ書いた関数の書き方"と理解しています。

ラムダ式書き方

まずusing Systemを追加する。

using System;

・引数無し 戻り値無しの関数の場合

Action型の変数に関数を入れてその変数に括弧()をつけて実行する。

Action aaa  = () => { 実行したい処理 }; 
aaa();


・引数有り 戻り値無しの関数の場合

Action型の変数に関数を入れてその変数に括弧()をつけて実行する。
引数の型はActionの直後に<>で記述する。

Action<引数の型> aaa  = (引数の型 引数の変数) => { 実行したい処理}; 
aaa(引数);


・引数無し 戻り値有りの関数の場合

Func型の変数に関数を入れてその変数に括弧()をつけて実行する。
Funcの直後に<>をつけてその中に戻り値の型を記述する。

Func<戻り値の型> aaa  = () => { return○○ }; 
Debug.Log(aaa());//戻り値をもっているので好きな変数に入れたりする


・引数有り 戻り値有りの関数の場合

Func型の変数に関数を入れてその変数に括弧()をつけて実行する。
Funcの直後に<>をつけてその中に引数の型、戻り値の型の順で記述する。

Func<引数の型,戻り値の型> aaa  = (引数の型 引数の変数) => 
{
 実行したい処理
 return○○ 
}; 
Debug.Log(aaa(引数の値));//戻り値をもっているので好きな変数に入れたりする

注)
引数が複数の場合、戻り値の型の記入は最後に記述する。
<第一引数の型,第二引数の型,・・・・・・,戻り値の型>

(ラムダ式を使ううえで、先にデリゲートの考え方を覚えた方がいいようです。)

ポイント

戻り値が無い場合はAction
戻り値が有る場合はFunc
を使うことだけ覚えておく。

サンプルコード

サンプル1 引数無し 戻り値無し 関数

・ 通常の関数の書き方

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

public class Ramudatest : MonoBehaviour
{    
    void Start()
    {
        aaa();
    }

    private void aaa()
    {
        Debug.Log("通常 引数無し 戻り値無し 関数");
    }      
}


ラムダ式での書き方

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;//ラムダ式を使用する場合 追加

public class Ramudatest : MonoBehaviour
{    
    void Start()
    {
        Action aaa = () =>{Debug.Log("ラムダ式 引数無し 戻り値無し 関数");};
        aaa();        
    }
}

サンプル2 引数有り 戻り値無し 関数

・通常の関数の書き方

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

public class Ramudatest : MonoBehaviour
{
    void Start()
    {       
        Test1(5);
    }

    private void Test1(int number)
    {
        Debug.Log(number*2);
    }
}


ラムダ式での書き方

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;//ラムダ式を使用する場合 追加

public class Ramudatest : MonoBehaviour
{
    void Start()
    {
        Action<int> aaa = (int number) => { Debug.Log(number*2);};
        aaa(5);
    }
}

サンプル3 引数無し 戻り値有り 関数

・通常の関数の書き方

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

public class Ramudatest : MonoBehaviour
{
    void Start()
    {
        Debug.Log(Test1());
    }

    private int Test1()
    {
        return 1;
    }
}


ラムダ式での書き方

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;//ラムダ式を使用する場合 追加

public class Ramudatest : MonoBehaviour
{
    void Start()
    {
        Func<int> aaa = () => { return 1; };
        
        Debug.Log(aaa());//返り値確認
    }
}

サンプル4 引数有り 戻り値有り 関数

・通常の関数の書き方

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

public class Ramudatest : MonoBehaviour
{
    void Start()
    {
        Debug.Log(Test1(6));
    }

    private int Test1(int number)
    {
        number = number * 3;
        return number;
    }
}

ラムダ式での書き方

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;//ラムダ式を使用する場合 追加

public class Ramudatest : MonoBehaviour
{
    void Start()
    {
        Func<int, int> aaa = (int number) =>
        {
            number = number * 3;
            return number;
        };

        Debug.Log(aaa(6));//戻り値をもっているので好きな変数に入れたりする
    }
}

省略した書き方

次の条件の時に一部を省略して書くことができます。
・引数が1つの場合()と型を省略できる。
・メソッド部分が1行の場合{}を省略できる。

実際にこちらのコードを省略してみます。

Action<int> aaa = (int number) => { Debug.Log(number * 2);};


・引数が1つの場合()と型を省略できる

Action<int> aaa=number=> { Debug.Log(number * 2);};


・メソッド部分が1行の場合{}を省略できる。

Action<int> aaa=number=>Debug.Log(number * 2);



また、引数が複数の場合、型のみ省略することができます。
・引数2つの基本コード

Action<int,float> aaa = (int number,float kazu) => { Debug.Log(number*kazu*2);};

・型のみ省略

Action<int, float> aaa = (number,kazu) => { Debug.Log(number * kazu * 2);};


・さらに、メソッド部分が1行なので{}を省略。

Action<int, float> aaa = (number,kazu) =>Debug.Log(number * kazu * 2);

おわりに

戻り値が無い場合はAction
戻り値が有る場合はFunc
を使うことだけ覚えておく。

有効な使い方はまだ見えていませんが、
ある程度ラムダ式のコードに心の耐性がついた気がします!
実際コードを読む場面では、省略されて書かれていることがほとんどなので、
省略のところは要チェックですね。

参考

squmarigames.com