そういうのがいいブログ

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

アプリ開発覚え書き

【Unity】Google Mobile Ads v6.1.2→v7.0.2 に上げた際のエラー対応

環境

Unityバージョン2021.3.3f1

2022.8.6追記
Unityバージョン2020.3.18f1では今回の対応が自動で行われていました。

はじめに

Google Mobile Ads v6.1.2→v7.0.2
とした時にはまったのでメモ

いろいろ過程でいじくりましたので参考程度に。


v6.1.2のパッケージでインポートしたファイルは全て削除し、
そこからv7.0.2のパッケージを入れています。

v6.1.2のファイルを削除するとアプリIDの設定がリセットされるため、
v7.0.2を取り込み後、アプリIDを入力してください。

また、パッケージを入れたのみで、広告のコードは書いていない段階のお話になります。

エラー内容

ビルド時、 R8が〜 JAVAが〜 というエラーが出てきますが関係ありませんでした。

対策

過程でいろいろいじくりまわしましたが、
対策は、競合ファイルを削除する。
これだけでした。
(再現の検証はしていませんので参考程度にして下さい。)

プロジェクトのところで「core」や「android」で検索すると、
バージョン違いの同名ファイルがあるので古いバージョンのファイルを削除して下さい。

画像内ので印をつけたファイルを削除しました。

おわりに

結果、単純なことでしたが、
検証などで朝活3日分潰しましたので、
どなたかの時短になれば報われます。

他の記事

marumaro7.hatenablog.com

【Unity】【Xcode】 Validate App エラー対応 Invalid Bundle. The bundle at '◯◯.app/Frameworks/UnityFramework.framework' contains disallowed file 'Frameworks'.

環境

MacOS:Monterey 12.4
Unity:2021.3.3f1
Xcode:13.4.1
Google Mobile Ads:v7.0.2
PlayFabSDK:2.138.220621

はじめに

XcodeでVaridate Appを行ったところ、

下記のエラーが発生しました。

Invalid Bundle. The bundle at '◯◯.app/Frameworks/UnityFramework.framework' contains disallowed file 'Frameworks'.


日本語訳

バンドルが無効です。 '◯◯.app/Frameworks/UnityFramework.framework'のバンドルには、許可されていないファイル'Frameworks'が含まれています。

※◯◯にはアプリ名が入ります。

対策

対策はこちらの記事の通りです。

zenn.dev

1.Editorフォルダ下にスクリプトを新規作成

「XcodeSwiftVersionPostProcess」という名前でスクリプトを新規作成
 作成したスクリプトをEditorフォルダ下に移動します。

2.スクリプト編集

スクリプト内容はこちらの内容にします。

using System.IO;
using UnityEditor;
using UnityEditor.Callbacks;
using UnityEditor.iOS.Xcode;
 
namespace Editor
{
    public static class XcodeSwiftVersionPostProcess
    {
        [PostProcessBuild(999)]
        public static void OnPostProcessBuild(BuildTarget buildTarget, string path)
        {
            if (buildTarget == BuildTarget.iOS)
            {
                ModifyFrameworks(path);
            }
        }
 
        private static void ModifyFrameworks(string path)
        {
            string projPath = PBXProject.GetPBXProjectPath(path);
           
            var project = new PBXProject();
            project.ReadFromFile(projPath);
 
            string mainTargetGuid = project.GetUnityMainTargetGuid();
           
            foreach (var targetGuid in new[] { mainTargetGuid, project.GetUnityFrameworkTargetGuid() })
            {
                project.SetBuildProperty(targetGuid, "ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES", "NO");
            }
           
            project.SetBuildProperty(mainTargetGuid, "ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES", "YES");
 
            project.WriteToFile(projPath);
        }
    }
}
 

スクリプト内容

先ほどのスクリプトは以下を自動で設定する内容となります。

Unity-iPhoneターゲットの場合、
「Always EmbedSwiftStandartLibraries」を"Yes"に設定する必要があります。

それ以外のターゲットの場合、
「Always EmbedSwiftStandartLibraries」を"No"に設定する必要があります。

参考

forum.unity.com

forum.unity.com

github.com

【Unity】iOS ビルドエラー BuildFailedException: Burst compiler (1.6.5) failed running stdout: Failed to determine xcode installation path - "xcode-select -p" is XCode installed? xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools),

バージョン

MacOS:Monterey 12.4
Unity:2021.3.3f1
Xcode:13.4.1
Google Mobile Ads:v7.0.2


はじめに

Google Mobile Adsを入れて初期設定しただけのプロジェクトで
Unityのビルドボタンを押したところ
下記のエラーが発生

BuildFailedException: Burst compiler (1.6.5) failed running

stdout:
Failed to determine xcode installation path - "xcode-select -p" is XCode installed? xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools), missing xcrun at: /Library/Developer/CommandLineTools/usr/bin/xcrun

stderr:



日本語訳

BuildFailedException:バーストコンパイラ(1.6.5)の実行に失敗しました
stdout:
xcodeのインストールパスを特定できませんでした-「xcode-select-p」はXCodeがインストールされていますか? xcrun:エラー:無効なアクティブな開発者パス(/ Library / Developer / CommandLineTools)、次の場所にxcrunがありません:/ Library / Developer / CommandLineTools / usr / bin / xcrun

stderr:

対策

Xcodeのパスが取得できていないとのことなので設定します。

ターミナルを開きます。




Xcode最新版に切り替えるため、ターミナルに以下を入力し、エンターを押します。
(ターミナルでの操作となりますので自己責任にてお願いします。)

sudo xcode-select --switch /Applications/Xcode.app




入力後、パソコンのパスワードの入力されるので入力します。
(パスワードを入力してもターミナル上には表示されません。)

パスワード入力後、特に変化はありませんが、設定完了です。

これでビルド再トライをしたところ、
Unityでのビルドが成功しました。

おわりに

ビルドは通りましたが、CocoaPodsアップデートしろのエラーが出たので別で書きます。

iOS framework addition failed due to a CocoaPods installation failure. This will will likely result in an non-functional Xcode project.

After the failure, "pod repo update" was executed and succeeded. "pod install" was then attempted again, and still failed. This may be due to a broken CocoaPods installation. See: https://guides.cocoapods.org/using/troubleshooting.html for potential solutions.

pod install output:

Analyzing dependencies
Adding spec repo trunk with CDN https://cdn.cocoapods.org/

CocoaPods 1.11.3 is available.
To update use: gem install cocoapods

For more information, see https://blog.cocoapods.org and the CHANGELOG for this version at https://github.com/CocoaPods/CocoaPods/releases/tag/1.11.3

[!] GoogleAppMeasurement requires CocoaPods version >= 1.10.2, which is not satisfied by your current version, 1.10.1.

追記
今回もこの内容でアップデートしてエラー無くなりました。

marumaro7.hatenablog.com

参考

answers.unity.com

com4tis.net

【Unity】AdMobのUnityAdsメディエーション設定 勝手にUnityAdsが停止していた話

はじめに

メディエーション設定していたUnityAdsが停止されたため経緯と対応をメモ

経緯

こちらのアプリをリリースした際、リワード広告のメディエーション設定をしており、
UnityAdsの広告が問題無く表示されている状況でした。

maruapps.com

メディエーションの設定方法はこちら

marumaro7.hatenablog.com

開発が進み、バナー広告を実装して
UnityAdsメディエーションを設定し、AdMobのメディエーション管理画面をみると、、、

「データが取得できません」と表示されるようになっていました。
(これに気付いたのはアップデートバージョンをリリースして一週間後とかなので、
表示されなくなったトリガーがわからない状態です。)

原因はUnityAdsダッシュボード

放置したり再設定したり、うまくいっているアプリの設定と見比べたり・・・
いろいろとやって見つけたのがこれ

Unityダッシュボードで広告が無効になっている!!!
そして有効にできない・・・

対応

Unityフォーラムを見る限り、
Unityに問い合わせるしかなさそうだったので問い合わせしました。

Unityダッシュボード
→Help and Support
→File a ticket
→Monetization
→Ads Fraud
で問い合わせました。
(Monetizeで問い合わせするとAds Fraudで問い合わせてねっって連絡きます(経験済み))

結果

下記返答があり、ここから2,3日で無事広告が有効になりました。
(OFFになっていた広告設定はUnity側で勝手ONに設定してくれてました。)

Hello,

Thank you for your patience.

We have taken the time to re-evaluate this case, and the fraud team has decided to reconcile this account. Please allow up to 24 hours for the Fraud team to process the reconciliation request. ,

Please make sure to read and follow our Monetization Terms of Service agreement to not generate any revenue through Invalid Activity, such as: - Triggering abnormal and continuous ad engagement patterns - Testing with live ads and triggering clicks and installs - Promoting incentivized clicks to end users - Promoting real world rewards including cash, gift cards, cryptocurrencies, etc. - Copyright infringement - VPN apps,

If there are signs of similar activity detected in the future, your account will be locked permanently.,

Revenue generated from fraudulent traffic will be reset, but you are welcome to use Unity Ads again.,

Regards,,

Unity Fraud Team

おわりに

エラー原因がUnityAdsダッシュボードの広告有効無効設定にあると
気付くまで2ヶ月くらいかかってしまいました。
(ずっと違う設定いじってました><)

この記事で早期改善に役立てていただければ幸いです。

他の記事

marumaro7.hatenablog.com

【iOS】 Certificate証明書の更新 (現在ご利用のiOS Distribution証明書の有効期限まであと30日になりました。)

はじめに

iOS Distribution Certificate証明書の更新方法になります。

証明書の有効期限は1年なので1年毎に行う必要があります。

やることは簡単なのですが、いつも忘れるのでメモ

1.証明書の作成

まずは、こちらの記事内容をそのまま行います。

marumaro7.hatenablog.com

こちらはiOSリリース手順ということで1〜5のシリーズになっています。
今回はシリーズ1の「証明書の作成 Certificate」の項目だけを行います。

初回時と違うこと

前回作ったCertificateSigningRequestファイルがあると思いますので、
上書きされないよう名前を変えて保存してやる必要があります。(上書きしても問題無いかも)
私は画像のように数字を入れて保存しています。

注意点

「1.証明書の作成」にて
CertificateSigningRequest.certSigningRequest ファイルを新しく作成したら
古い方のファイルは必ずゴミ箱へ移動してください。
Xcodeでストアへアップロードする過程で権限エラー?が発生します。

2.Profilesの更新

デベロッパーサイトのProfilesにアクセス
https://developer.apple.com/account/resources/profiles/list

更新したいProfileを選択します。
(今回は赤枠のものを更新します。)


このような画面になるので「Edit」を押す。


Certificateを選択する画面になるので、
今回作ったCertificateを選択する(有効期限が一番長いもの)
→Save


Profileが作成されるのでDownloadを押す。


ダウンロードしたファイルをダブルクリックしてXcodeに適用する。
(ダブルクリックすれば勝手にXcodeが起動します。)


他にもアプリを出しているのであれば、
そのProfileを選択して上記の「Edit〜Xcodeに適用」を繰り返してください。

おわりに

スムーズに更新できましたら幸いです。

Unity本を出版しました!

突然ですが、Unity本を出版しました!
こちらを読むことで、スクリプトの基礎固めができます!
現在、kindle unlimitedで読み放題設定中です。今のうちにどうぞ!


もっと早く教えてほしかった!Unity C#入門

他の記事

marumaro7.hatenablog.com

【Unity】LitJsonでジャグ配列を文字列へ変換する

はじめに

LitJsonでジャグ配列を使う メモ

・Unity標準のJsonUtilityではジャグ配列を文字列に変換できない
・LitJsonを使用すれば使えるようになる
ということでLitJsonを使用していきます。
使用するにはまず、前準備が必要です。

前準備

Githubからファイルをダウンロードします。
github.com

Code→DownLoad ZIP
f:id:marumaro7:20220319042353p:plain

ダウンロードしたファイルの「src」というフォルダを
UnityのAssetsに入れます。
f:id:marumaro7:20220319043524p:plain

これで準備完了です。

使い方1

いきなりジャグ配列を使うとわかりにくいので、
int型とstring型の変数を使ったサンプルを載せます。
やっていることは下記です。
・セーブされた文字列を元のクラスの形に戻す(セーブデータがあれば)
・変数を変更
・文字列への変換&セーブ

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

using LitJson;

public class LitJsonTest : MonoBehaviour
{
    string json;

    private void Start()
    {
        Player player = new Player();

        //セーブキーを持っていたら処理
        if (PlayerPrefs.HasKey("SaveKey"))
        {
            json = PlayerPrefs.GetString("SaveKey");//セーブデータから文字列を読み込み

            print("json = " + json);

            player = JsonMapper.ToObject<Player>(json);//読み込んだ文字列からPlayerクラスの値を設定

            print("HP = " + player.hp);
            print("Name = " + player.name);
            print("SkillName = " + player.skillName);
        }


        //データを変更
        player.hp += 10;
        player.name = "勇者";
        player.skillName = "abc";

        json = JsonMapper.ToJson(player);//playerクラスを文字列に変換
        PlayerPrefs.SetString("SaveKey", json);//文字列をセーブ

        print("json = " + json);
    }
        
}

public class Player
{
    public int hp;
    public string name;
    public string skillName;
}

結果

初回実行時(セーブデータがないので変数の変更 と 保存のみ) f:id:marumaro7:20220319053836p:plain

2回目実行時 f:id:marumaro7:20220319053949p:plain

ポイント

名称の書き方が不適切かもしれませんが、重要なのはこの2つです。

文字列への変換

JsonMapper.ToJson(変換したいクラス);

文字列からクラスへの変換

JsonMapper.ToObject<クラス名>(保存していた文字列);

ジャグ配列を使用

本題のジャグ配列を文字列へ変換するサンプルです。
先ほどのサンプルで書いていたPlayerクラスの変数はジャグ配列一つにしました。

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

using LitJson;

public class LitJsonTest : MonoBehaviour
{
    string json;

    private void Start()
    {
        Player player = new Player();

        player.skillId = new int[3][];//最初の要素数の指定

        player.skillId[0] = new int[2];
        player.skillId[1] = new int[3];
        player.skillId[2] = new int[4];


        //セーブキーを持っていたら処理
        if (PlayerPrefs.HasKey("SaveKey"))
        {
            json = PlayerPrefs.GetString("SaveKey");//セーブデータから文字列を読み込み

            print("セーブデータから読み込んだjson = " + json);

            player = JsonMapper.ToObject<Player>(json);//読み込んだ文字列からPlayerクラスの値を設定
                        
            for (int i = 0; i < player.skillId.Length; i++)
            {
                for (int n = 0; n < player.skillId[i].Length; n++)
                {
                    print("復元後SkillId" + "[" + i + "][" + n + "] = " + player.skillId[i][n]);
                }
            }
        }


        //データを設定
        for (int i = 0; i < player.skillId.Length; i++)
        {
            for (int n = 0; n < player.skillId[i].Length; n++)
            {
                player.skillId[i][n] = i + n;
            }
        }

        json = JsonMapper.ToJson(player);//playerクラスを文字列に変換
        PlayerPrefs.SetString("SaveKey", json);//文字列をセーブ

        print("セーブしたjson = " + json);
    }
        
}

public class Player
{
    public int[][] skillId;
}


結果

初回実行時 f:id:marumaro7:20220319060653p:plain

2回目実行時 f:id:marumaro7:20220319061233p:plain

ジャグ配列の文字列化と復元ができることが確認できました。

おわりに

Unity標準のJsonUtilityの方が処理速度が早いらしいので
JsonUtilityで処理できないときだけLitJsonを使うと良さそうです。

参考

blog.lab7.biz

nekosuko.jp

【Unity】Humanoid型モデルで使用するAnimationClipのキーフレームをスクリプトから変更する方法 SetCurve モバイル不可

はじめに

Humanoid型モデルのアニメーションをスクリプトから行いたかったのでメモ

私の調べた結果ですと、
Humanoid型モデルのアニメーションを変更できるのはエディター内のみで、
モバイル上で変更する方法は無いようです。

前提知識

AnimationClipは、特定のプロパティ(Transformなど)の
数値を登録することで、アニメーションさせています。

Hunanoide型のキャラクターをアニメーションさせる場合には、
キャラクターの各ボーンの角度ではなく、マッスル値で設定するのが一般的なようです。
(私は調べるまでボーンの角度を調整していると思っていました...)

↓これは、あるポーズのAnimationClipの設定画面です。
 Animatorの中のマッスル値が登録されています。
f:id:marumaro7:20220310054457p:plain:w200

マッスル値に関してはこちらの記事に書いています。

marumaro7.hatenablog.com

キーフレームをスクリプトから変更

方法は簡単で次の2ステップです。
1.AnimationCurveで変化内容を設定
2.AnimationClip.SetCurveで変化内容を適用

AnimationClipへの「指定したプロパティのキーフレーム」は、
AnimationClip.SetCurveで変更することができます。

docs.unity3d.com

このSetCurveで指定したプロパティがAnimationClipに
存在するかどうかで挙動は少し変わります。
・同じプロパティ無:AnimationClip内に新規作成
・同じプロパティ有:内容の更新

サンプル

3種類のマッスル値をAnimationClipに追加するスクリプトです。

public AnimationClip animationClip;//変更するアニメーションクリップを割り付け

public void Test()
{
     //animationClip = new AnimationClip();//アニメーションクリップを作成 スクリプト内でAnimationClipを新規作成する場合
     //値の変化を設定
        //Linear⇒直線的な変化
        //引数(開始時間, 開始値, 終了時間, 終了値)
        AnimationCurve curve1 = AnimationCurve.Linear(0, 0.5f, 0, 0);
        AnimationCurve curve2 = AnimationCurve.Linear(0, 0.5f, 0, 0);
        AnimationCurve curve3 = AnimationCurve.Linear(0, 0.5f, 0, 0);

        //アニメーションカーブの中にキーフレームを追加(必要であれば)
        //引数(時間, 値)
        //時間:キーを追加する時間(カーブグラフにおける水平軸)
        //値 :キーの値(カーブグラフにおける垂直軸)
        //Keyframe key = new Keyframe(10f, 10f);


        //アニメーションカーブ1にキーフレームを追加(必要であれば)
        //curve1.AddKey(key);

        //アニメーションクリップにアニメーションカーブをセット
        //引数(パスの指定, タイプ, 操作項目名, アニメーションカーブ)
        //SetCurveはユニティ上ではできるがモバイル実機ではできない 公式に記述あり https://docs.unity3d.com/ScriptReference/AnimationClip.SetCurve.html
        animationClip.SetCurve("", typeof(Animator), HumanTrait.MuscleName[1], curve1);
        animationClip.SetCurve("", typeof(Animator), HumanTrait.MuscleName[2], curve2);
        animationClip.SetCurve("", typeof(Animator), HumanTrait.MuscleName[4], curve3);
}

空のAnimationClipを使ってこちらのコードを実行すると、
アニメーションクリップ内に指定したプロパティのキーフレームを打つことができます。
注意:AnimationClipの内容は保存されます。 f:id:marumaro7:20220311054156p:plain

1.AnimationCurveで変化内容を設定

AnimationCurve型の変数を宣言し内容を設定します。
AnimationCurve.カーブの種類(開始時間, 開始値, 終了時間, 終了値); で設定します。  

AnimationCurve curve1 = AnimationCurve.Linear(0, 0.5f, 0, 0);

2.AnimationClip.SetCurveで変化内容を適用

AnimationClipにアニメーションカーブをセットします。
AnimationClip.SetCurve(パスの指定, プロパティの型, 操作項目名, アニメーションカーブ)で設定します。

animationClip.SetCurve("", typeof(Animator), HumanTrait.MuscleName[1], curve1);

引数1:パスの指定
""で自動的に現在のパスが割り付けられるので""で問題ありません。

引数2:プロパティの型
今回設定するマッスル値は、Animatorの中の値なのでAnimatorと書きます。

引数3:操作項目名
"引数2"で設定したプロパティの型の中のどの項目の数値を変更・追加するかをを設定します。
今回、型はAnimatorの中のマッスル値を設定したいので、マッスル値の名前を設定します。
マッスル値の名前は、
HumanTrait.MuscleName[マッスル値の配列番号]
で取得することができます。

引数4:アニメーションカーブ
「1.AnimationCurveで変化内容を設定」で設定したAnimationCurveの情報を入れます。

補足:アニメーションカーブにキーフレームを追加

私は使用していないので紹介のみですが、
サンプルでコメントアウトしている下記のコードで
アニメーションカーブの中にキーフレームを追加できるようです。

      //アニメーションカーブの中にキーフレームを追加(必要であれば)
        //引数(時間, 値)
        //時間:キーを追加する時間(カーブグラフにおける水平軸)
        //値 :キーの値(カーブグラフにおける垂直軸)
        //Keyframe key = new Keyframe(10f, 10f);


        //アニメーションカーブ1にキーフレームを追加(必要であれば)
        //curve1.AddKey(key);

モバイル不可

今回使用したAnimationClip.SetCurveをモバイルで使用するには、
このコードを追加する必要があります。([詳細は公式参照]
(https://docs.unity3d.com/ScriptReference/AnimationClip.SetCurve.html))

animationClip.legacy = true;

しかし、この設定は、
AnimationClipを 廃止予定であるAnimationコンポーネントで使用するためのものです。
Animationコンポーネントではマッスル値は対応していないようで追加ができませんでした。

逆にAnimationコンポーネントで制御できるプロパティであれば、
モバイルからでも設定変更ができます。

余談

全然関係ないですが、
SpriteRendererをアニメーションさせる場合の
PropertyNameは”m_Size.x”のように m _が必要なようです。

プロパティ名は予測変換ではでなかったので、
一旦手動でアニメーションを作ってプロパティ名を確認する作業が必要です。

参考
teratail.com

おわりに

モバイルで動作させたかったのですが、現状無理なようでとても残念でした。
できないことがわかったということで良しとしています。

もし、AnimatorのAnimationClipのプロパティをモバイルから変更する方法を
ご存知の方がいらっしゃいましたら情報お待ちしています。


また、Animationコンポーネントのアニメーションならモバイルで設定できるわけですが、
それなら神アセットのDoTween使えばいいやと思っています。

エディター上でアニメーション作る際、今回の知見が使えそうですが、
自分で環境整えるより、Very Animationを使った方が遥かに早そうです。

assetstore.unity.com

他の記事

marumaro7.hatenablog.com

参考

www.natsuneko.blog

teratail.com

buravo46.hatenablog.com

learning-collection.com

mebiustos.hatenablog.com