Assets\Plugins\Android\mainTemplate.gradle 内にて、**DIR_UNITYPROJECT** が展開されないという不具合の暫定修正
次のようなエラーメッセージが出る場合
A problem occurred configuring project ':unityLibrary:GoogleMobileAdsPlugin.androidlib'.
Could not create an instance of type com.android.build.api.variant.impl.LibraryVariantBuilderImpl.
Namespace not specified.
Please specify a namespace in the module's build.gradle file like so
- プロジェクト設定
- プレイヤー
- Android
- 公開設定
- カスタムGradle設定テンプレートをON
"C:\MyProjectFolder\Assets\Plugins\Android\settingsTemplate.gradle"
以下の maven {} の部分を追加
repositories {
**ARTIFACTORYREPOSITORY**
maven {
url "file:///C:/MyProjectFolder/Assets/GooglePlayGames/com.google.play.games/Editor/m2repository"
}
google()
mavenCentral()
}
2023/06/35 16:35 追記
Google Mobile Ads プラグイン v8.3.0 に更新したら、上記修正と同じコードが入った。よって「カスタムGradle設定テンプレートをON」のみ行えば良さそう。
Sprite Atlas スプライトアトラス
小さい画像を一つにまとめる事で描画負荷を減らす。
エディタ設定を変更する際に、Always ではなく Enabled for
Builds にする。そうしないと編集中に警告が出続ける
まずは最高品質にして、問題がない範囲で変更
- 回転を許可をOFF
- タイトパッキングをOFF
- アルファ拡張をON
- パディングを8
- フィルターモードをポイント
- 画像の形式はRGBA 32bit
フォルダ指定時は、「パックするオブジェクト」の部分にドロップする
テスクチャタイプは「スプライト(2DとUI)」にする必要があるので、パーティクルのテクスチャは行わない
addressablesとの関係性
グループが一つしかないなら気にしなくて良いようだった
AdMobについて
- 審査期間は広告配信無し
- 通常は24~48時間で審査完了
- 承認されれば広告出る
- 不承認ならポリシーセンターの内容解決して再審査出してね
- リリース前のテストはテストモード、テスト広告ユニット使ってね
-
アプリをリリースする
-
Admobの管理画面でリリースされたアプリとAdmobをリンクさせる必要がある
-
リンクが完了するとAdmob側で審査が走り、審査が完了すると本番で広告が表示される
- 審査開始が22時、審査完了メールが来たのが翌午前4時だった
-
→試しにやってみたが、「アプリにストア情報を追加する」で検索しても見つからないので公開が先
リリースビルドをする際の設定箇所
- キーストアでアプリの名前を追加して専用のパスワードを作成
- 開発ビルド OFF。キーストアからパスワード二つ
-
Symbles.zipを作成。登録で使う
- C++ コンパイラ設定 Release 。Masterは不具合が出ないなら
- StrippingLevel は Low。Middle以上は不具合が出ないなら
- IL2CPP コード生成は、より速いランタイム
- 「App Bundle でビルド(Google Play)」にチェック
- コード圧縮でリリースにチェック。
- R8はproGuardとどちらを採用するか。R8はGoogle、proGuardはある企業の開発
-
バージョン番号変更。Android はさらにバージョンコード
- Unityのメジャーまたはマイナーのバージョンが上がるころに検討
- 上書き前に前のファイルをバックアップ。以前動作しなくなったことがあったため
ビルドエラー
SDK32以降だと UnityEngine.SystemInfo.deviceName がエラーになる。
PlayFab.Partyで使われているので、手動で変更
権限について
API23以降は、Unity上で確認できるらしい
今更変えられないので、新しいアプリを作る時に利用
QRコード
作成
コインイメージを作成したのと同じようなコード
バイナリそのままは入らないのでBase64
読み取り
もちろんカメラ権限がいる
ライセンス Apache License 2.0
他のライブラリも含むようなので、それらも確認
アセットストアにあるものは有料のみ
動作時警告
2023/03/04 14:45:09.545 16801 17238 Warn ****.**** Accessing hidden method Lcom/android/org/conscrypt/ConscryptEngineSocket;->setUseSessionTickets(Z)V (max-target-q,core-platform-api, reflection, denied)
2023/03/04 14:45:09.545 16801 17238 Warn ****.**** Accessing hidden method Lcom/android/org/conscrypt/OpenSSLSocketImpl;->setUseSessionTickets(Z)V (max-target-q,core-platform-api,reflection, denied)
2023/03/04 14:45:09.545 16801 17238 Warn ****.**** Accessing hidden method Lcom/android/org/conscrypt/AbstractConscryptSocket;->setUseSessionTickets(Z)V (max-target-q, reflection, denied)
2023/03/04 14:45:09.545 16801 17238 Warn ****.**** Accessing hidden method Lcom/android/org/conscrypt/ConscryptEngineSocket;->setHostname(Ljava/lang/String;)V (max-target-q,core-platform-api, reflection, denied)
2023/03/04 14:45:09.545 16801 17238 Warn ****.**** Accessing hidden method Lcom/android/org/conscrypt/OpenSSLSocketImpl;->setHostname(Ljava/lang/String;)V (max-target-q,core-platform-api, reflection, denied)
2023/03/04 14:45:09.545 16801 17238 Warn ****.**** Accessing hidden method Lcom/android/org/conscrypt/AbstractConscryptSocket;->setHostname(Ljava/lang/String;)V (max-target-q, reflection, denied)
2023/03/04 14:45:09.545 16801 17238 Warn ****.**** Accessing hidden method Lcom/android/org/conscrypt/OpenSSLSocketImpl;->setAlpnProtocols([B)V (max-target-q,core-platform-api, reflection, denied)
2023/03/04 14:45:09.545 16801 17238 Warn ****.**** Accessing hidden method Lcom/android/org/conscrypt/AbstractConscryptSocket;->setAlpnProtocols([B)V (max-target-q, reflection, denied)
com.squareup.okhttp3:okhttp を更新する?
→ 互換性の問題があるようなので保留
FindObjectOfType より FindAnyObjectByType の方が実行効率が良い
#if UNITY_2021_3_18_OR_NEWER
var nextScene = FindAnyObjectByType<SettingsSceneScript>();
#else
var nextScene = FindObjectOfType<SettingsSceneScript>();
#endif
同じく FindObjectsOfType より FindObjectsByType を使う。
#if で囲っているのは、不具合調査でバージョンを戻すことがあったため。
Google Play Console の自動テストでタップターゲットサイズが小さいという警告
解決できなかった
UniTaskでのタイムアウトの書き方
デュエル中の通信でフリーズする。
原因が不明なので、そこだけ Observable.Timeout の実装とした。
スレッドに関係しそうではある。
UI.Text でサイズ自動調整をしても大きくならない場合
日本語に対応した折り返しルールになっておらず、空白を開けるなどしないといけないため。
以下を元に日本語を考慮した折り返しをする事で対処できた。
HyphenationJpn.GetText でスクリプト上からテキストを設定できる。SetTextではないが正しい。
スクリプト内で水平オーバーフローに変更した後に戻していないが、スクリプトが改行を入れる前提であるため。
しかし一部メッセージで枠外に出てしまう事があった。
本来不要だが処理後に戻すよう修正した。結果文字サイズが小さくなったがやむを得ず
さらに別の文章では、おかしい位置で改行された。文章には自分で改行を入れていたが、入れないようにして回避した
Google Mobile Ads のバナー、インタースティシャル、リワードの各イベントにある OnAdPaid は呼ばれない。
呼ばれるようにするには、 AdMob内で設定する
得た広告と同じ量のポイントをユーザーに与えるために使えそうだが、
どれぐらい通信が発生するかが不安なので適用していない
レビューボタンが効かない
proguardに追加
-keep public class com.google.android.play.core.**{
public *;
}
一回レビューすると一か月変更できない
→エラーが返ってきたらストアページを開く
警告
Mapping new ns http://schemas.android.com/sdk/android/repo/sys-img2/02 to old ns http://schemas.android.com/sdk/android/repo/sys-img2/01
System.Threading.ThreadHelper:ThreadStart ()
という警告が複数出る。
ビルドツールを更新すると直る、という説明があるが、Unityなので出来ない。
Unityが対応するしかなさそうだが、更新したら直ったという記事もあり、一過性の物かも
Unity から Android のプロジェクト出力してビルドする場合にやった事
ビルド時にエラー、または端末にインストールする際にエラーが出る場合
キーストアのパスワード入力を確認する。
一度パスワードありでインストールした場合、無しで入れるにはアンインストールが必要だろうという予想
圧縮(minify)で動かない場合
- デバッグビルドでも圧縮してみる
-
エラーが出るままでいいので Google Play Console で内部テストで公開してみる
- デバッグシンボルを付けるので、より詳細なエラーが確認できる
-
圧縮ありとなしぞれぞれで作って、Android Studio のメニュー → ビルド → Analize Apk で中身を比較する
- base → dex → classes.dex を選択。圧縮無しだと複数ある
- 圧縮ありはマッピングファイルを選択
- 比較した結果無くなっている名前空間があったら proguard-user.txt に追記してみる
-keep class com.microsoft.** {
*;
}
-keep class com.bumblelion.** {
*;
}
Google Play Console
内部テストでメーリングリストを設定したいが、メーリングリストの設定が出てこない
→アプリの選択ではなく全てのアプリの状態にするとメニュー構成が変わる
→メーリングリストがアプリごとではなく全体の設定であるため
リリースノート
<ja-JP>
ファーストリリース
</ja-JP>
<en-US>
first release
</en-US>
同じバージョンを再度出そうとすると、既にあるというエラーが出る。名前を変えるか、左パネル内 App Bundle エクスプローラから消す。
→バージョンは表示名ではなく「バンドルバージョンコード」を元にする。整数なのでバージョンが1.0.0なら 1 00 00 のように2桁ずつの値などにする
リリースでの警告
難読化解除ファイルの指定
→プレイヤー設定 → Android 公開設定 → ファイル圧縮 → リリース にチェックを入れるとファイルが増えた
→ aabファイルを指定しただけで警告が消えた。自動的に取り込まれたのかaabファイルに含まれるのか
リリースビルドで強制終了
Exception java.lang.ExceptionInInitializerError:
at java.lang.Class.newInstance (Class.java)
at android.app.AppComponentFactory.instantiateProvider (AppComponentFactory.java:147)
at androidx.core.app.CoreComponentFactory.instantiateProvider (CoreComponentFactory.java)
at android.app.ActivityThread.installProvider (ActivityThread.java:7411)
at android.app.ActivityThread.installContentProviders (ActivityThread.java:6939)
at android.app.ActivityThread.handleBindApplication (ActivityThread.java:6710)
at android.app.ActivityThread.access$1500 (ActivityThread.java:247)
at android.app.ActivityThread$H.handleMessage (ActivityThread.java:2053)
at android.os.Handler.dispatchMessage (Handler.java:106)
at android.os.Looper.loopOnce (Looper.java:201)
at android.os.Looper.loop (Looper.java:288)
at android.app.ActivityThread.main (ActivityThread.java:7839)
at java.lang.reflect.Method.invoke (Method.java)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:548)
at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1003)
Caused by java.lang.IllegalStateException: Could not find Library Package Name in BuildConfig.
at com.microsoft.playfab.party.PartyLibInitializationProvider.getPackageName (PartyLibInitializationProvider.java)
at com.microsoft.playfab.party.PartyLibInitializationProvider.<clinit>(PartyLibInitializationProvider.java)
原因は最適化
C:\MyProjectFolder\Assets\Plugins\Android\proguard-user.txt
に、以下を追加した。
-keep class com.microsoft.playfab.party.BuildConfig {
public <fields>;
}
Google Play Console でアプリの詳細を App Bundle Explorer で見た時に、対応言語がほとんど含まれる。
以下の両方に書く。表示上は launcher だけでいいかもしれないが、mainの方はリソースデータも減るかも
C:\MyProjectFolder\Assets\Plugins\Android\mainTemplate.gradle
C:\MyProjectFolder\Assets\Plugins\Android\launcherTemplate.gradle
以下調査
外部ライブラリにより自動的に追加されたpermissionは、プロジェクトの AndroidManifest.xml で以下のように書くと消せる。
<uses-permission android:name="android.permission.RECORD_AUDIO" tools:node="remove"/>
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" tools:node="remove"/>
<uses-permission android:name="android.permission.BLUETOOTH" tools:node="remove"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" tools:node="remove"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" tools:node="remove"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" tools:node="remove"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" tools:node="remove"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" tools:node="remove"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" tools:node="remove"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" tools:node="remove"/>
本質的にはライブラリ側を修正すべきだが調べるのも面倒なので。
BLUETOOTH 等は uses-permission-sdk-23 でも宣言しているが、上記で uses-permission の宣言だけ消せた
Androidビルド後の最終的なAndroidManifest.xmlファイル
aab でも開ける
Android Studio
メニュー ビルド → Analize APK
base → manifest → AndroidManifest.xml
BuildConfig.class も同じように探せる。
クラスがアルファベット順ではない事に注意
NearByで通信時に警告が出る
01/02 13:53:52.550 11621 11621 Warn Unity AndroidJNIHelper.GetSignature: using Byte parameters is obsolete, use SByte parameters instead
01/02 13:53:52.550 11621 11621 Warn Unity UnityEngine.Logger:Log(LogType, Object)
01/02 13:53:52.550 11621 11621 Warn Unity UnityEngine._AndroidJNIHelper:GetSignature(Object)
01/02 13:53:52.550 11621 11621 Warn Unity UnityEngine._AndroidJNIHelper:GetSignature(Object)
01/02 13:53:52.550 11621 11621 Warn Unity UnityEngine._AndroidJNIHelper:GetSignature(Object[])
01/02 13:53:52.550 11621 11621 Warn Unity UnityEngine._AndroidJNIHelper:GetMethodID(IntPtr, String, Object[], Boolean)
01/02 13:53:52.550 11621 11621 Warn Unity UnityEngine.AndroidJNIHelper:GetMethodID(IntPtr, String, Object[], Boolean)
01/02 13:53:52.550 11621 11621 Warn Unity UnityEngine.AndroidJavaObject:_Call(String, Object[])
01/02 13:53:52.550 11621 11621 Warn Unity GooglePlayGames.Android.PayloadCallback:onPayloadReceived(String, AndroidJavaObject)
これは既存の不具合で、byte と SByte の変換によるもの。
NearByはライブラリ内なので修正出来ない。
この警告は無視するか、byte を使わずBase64で文字にして渡す事で回避
マネージドストリッピングレベルは 低 または Minimal にする。
中以上だと PlayFabPartySDKの SDK.PartyStartProcessingStateChanges 辺りで NullReferenceException が起きる。
IPointerClickHandler で、Z軸0以上しかクリックを受け付けない事があった。
カメラを真上近くに移動する事で解消したが、原因は不明なまま。
描画最適化
Unityに統合されている
プレイヤー設定 Android → 画面と解像度 → 最適化されたフレームページング(Optimized
Frame Pacing)
関連。有効にすると重くなる
→既に有効だった。
60/30/20fpsであることを確認する。
改ざん防止
- バイナリ改ざん
- 正規のストアからのインストール
- 正規の端末
サーバーへの送信データ保護も出来るが、コストもあるのでリアルタイム通信は出来ない。
実装も複雑なので、課金アイテム実装時に検討
ビルドエラー
android のプラグインが変化した後のビルドで、NotSupport とか、ARMv7で使用できないとかメッセージが出た時は、
Library フォルダを消してから再ビルドする。
ビルドエラー
File C:\Users\UserName\.android\repositories.cfg could not be loaded.
というエラーが出た時
同パスを空テキストファイルで作る
最適化
コード上で詳細を調べたい箇所に実装する
最適化
Project Auditor
指摘されたが有効化しなかったもの
-
Vulkan
- OSレベルではAndroid7から。6をターゲットに含めているため適用しない事とした。
-
Physics Settings の Reuse Collision Callbacks オプション
-
時間設定で、Fixed Timestepはデフォルト値の0.02に設定されています。
- フレームレートを設定で変更できるので、スクリプトで適切な値を設定している。
-
- フレームレートを設定で変更できるので、スクリプトで適切な値を設定している。
Project Auditor 以外の指摘
- 階層を減らし、Transform の影響範囲を最適化
-
Instantiate を使って作成する際、その後に必ず位置を変更するはず。引数指定で使う。
-
- Read/Write Enabled オプションを無効にする
- 不要なミップマップを無効にする
- 圧縮 ETC2
-
カメラを減らす
- デュエル中は途中でトークンのコインが増える場合もあるのでそのまま
パフォーマンスチューニング
- 176ページ
- material は複製を返すので、明示的にDestroyが必要
- 255ページ
- transform へのアクセス。SetPositionAndRotate を使う
- Texture2D、Sprite、Material、PlayableGraph などは、明示的にDestroyが必要
- 266ページ
- ラムダ式はGC.Allocが発生する
- 参照するのがstatic変数なら発生しない
- 参照するのがstatic関数の場合、()=>{func();}の書き方だと、一回だけは作成されるが以降は問題ない。
- 代替がないので、重いところだけにする
- 292ページ
- DOTWeen関連の最適化
- SetLinkを付ける、Killする、await
- 実行中に[DGWEEN]の項目を選択しておくと実行されているアニメーションが表示される。
- 295
- UniRxの購読はOnDestroyで解除するか、AddTo(this)を付ける
フェードインがちらつく
- Startでフェードイン前に行う処理の中にファイル読み込みがあると起きる事があった。
Project Auditor
- 修正しない
- Material.material を .sharedMaterial に変える
-
得たマテリアルを変更しないなら変えていい。変更するなら.materialにする。そうしないとアセット内のマテリアルファイルが編集される
使わない方がいい物
-
GetComponent
- 代わりにスクリプトを作ってエディタ上で関連付けしておく。数が多いならプレファブ化
public class ButtonScript : MonoBehaviour
{
public Button Button;
public Image Image;
}
-
GameObject.name
-
Linq
-
-
-
Resources 以下にファイル
ビルドサイズについての公式マニュアル。上記に含まれている。
Android ビルドエラー
java.lang.UnsupportedOperationException: This feature requires ASM7
ビルドボタンのドロップダウンのクリーンビルドを行う
Library フォルダを消してからやり直しても可能
Editor と Android でバナーの大きさが違う
理由はdpiが違うため
Editor dpi=168
Android1 dpi= 440
Android2 dpi= 480
実際の高さは以下で求まる
static float GetBannerHeight()
{
float f = Screen.dpi / 160f;
float dp = Screen.height / f;
if (720f < dp) return 90f * f;
if (400f < dp) return 50f * f;
return 32f * f;
}
環境全てを考慮して場所を開けるのは難しいので、動的に行うようにした。
-
Canvasの子にGameObjectを作り、アンカーをStretchAllにする
-
元々の子全てを、追加したGameObjectの子にする。
-
シーンのAwakeで、追加したGameObjectのサイズを変える
public void SetBannerSpace(RectTransform canvasInner)
{
Vector2 offsetMin = Vector2.zero;
Vector2 offsetMax = Vector2.zero;
if (UserSettings.Instance.UseAdBannerTop)
{
offsetMax = new Vector2(0, -GetBannerHeight());
}
else if (UserSettings.Instance.UseAdBannerBottom)
{
offsetMin = new Vector2(0, GetBannerHeight());
}
canvasInner.offsetMin = offsetMin;
canvasInner.offsetMax = offsetMax;
}
SingletonMonoBehaviour
派生先で Awake を実装してはいけない。(ビルドエラーにならない)
SingletonMonoBehaviour.Awake が呼ばれなくなり、シングルトンにならなくなる
エラー
前後に広告関連のログがあったので、広告表示によって起きた可能性
→ 問題は、リワードビデオを再生した後、ユニティがメインスレッドに再び切り替わる前にユニティメソッドを呼び出すことができないことだと思います。onApplicationPause
が呼び出されるまで待つ必要があります。
Editorでは起きない。設定を変更しないと OnApplicationPause が呼ばれない為
Android では OnApplicationFocus に変える必要もありそうだ
bool isBackground = false;
private void OnApplicationFocus(bool pause)
{
OnChangePause(!pause);
}
private void OnApplicationPause(bool pause)
{
OnChangePause(pause);
}
void OnChangePause(bool pause)
{
if (isBackground == pause) return;
isBackground = pause;
// 停止から復帰した時
if (!pause)
{
// 処理
}
}
広告の各イベントで、広告が出たことを記録。pauseが解除されたときに処理する。
Google Mobile Ads を更新する場合
C:\MyProjectFolder\Assets\ExternalDependencyManager
を丸ごと削除
C:\MyProjectFolder\Assets\GoogleMobileAds\Resources
とそのmetaファイルを退避
C:\MyProjectFolder\Assets\GoogleMobileAds
を丸ごと削除
新しいパッケージを取り込む。上記以外のフォルダのファイル上書きは確認する
C:\MyProjectFolder\Assets\GoogleMobileAds\Resources
を戻す
Editor の再起動を何度か繰り返す
Google Play Games Plugin で、ビルドごとに「Warning!! Google Play Games was not configured, Game Services will not work correctly.」が出る件
理由は、以下から構成をしていないため。
Window > Google Play Games > Setup > Android Setup...
構成情報をGoogle開発者コンソールから得て貼ればいいだけだが、それをすると、ゲーム起動ごとに「ようこそ●●さん」が出る事と、
実績機能が必ず有効化されるため。
どちらも不要であり NearBy で必要なだけなので、コード上から削除した
C:\MyProjectFolder\Assets\GooglePlayGames\com.google.play.games\Editor\GPGSPostBuild.cs
ちなみに上記ページには
NearBy Connection を使用するために、プレーヤーを認証する必要はなく、Google Play デベロッパー コンソールの構成も必要ありません。
という分もあるので問題なさそうだ
ストアページ開くを付ける
Application.OpenURL
Application.OpenURL($"market://details?id=com.{Application.companyName}.{Application.productName}");