📚

Unity その他 メモ

2024/02/21に公開

メモしたのを書きなぐります

メモしたのを書きなぐります

・Android Logcat
Androidで端末に接続して、リアルタイムでデバッグログのログをUnityでエディタ上で確認できる
参照サイト参照サイト

・Code Coverage
Test Runnerで、確認したいメソッドがテストがされているか確認
参照サイト

・Editor Coroutines
コルーチンをエディター上で実行できる
参照サイト

・Profile Analyzer
Profile Analyzerを使用して、フレーム間の負荷を図ったり、2つのプロファイルしたデータを比較して最適前・後を比較しよう
参照サイト参照サイト参照サイト

・Profiling Core API
Profiler使用の際、メタデータやカスタムグラフを表示できる
参照サイト

・バグレポ
Diagnosticsというエラーやクラッシュを監視するUnity公式サービス
参照サイト

・開発ビルドのみ処理を実行させたい
参照サイト

・実機でプロファイルを確認しながらテスト
参照サイト

・実機上、ブレイクポイントで処理の確認、また変数の値の確認
参照サイト

・Device Simulator を使用して実機のレイアウトテストを簡単に行おう
参照サイト参照サイト参照サイト参照サイト参照サイト

・Memory Profilerを使用して、メモリの使用量を把握しやすくしよう
また、スナップショットを保存して比較することで、より簡単にメモリリークを発見したり、メモリレイアウトを確認してメモリの断片化の問題を発見したりできる。
参照サイト参照サイト参照サイト

・ProguardまたはR8で、難読化・ディスクサイズの削減を行う
ただ、Andoridのプラグインを使用するとビルド時にストリップされるので対処が必要
参照サイト参照サイト参照サイト

・Metal API Validationをオンにすると、問題があればエディタに出力される
ただ、CPUの負荷を食うのでリリース時にはオフにすると良い
参照サイト

・iOSシュミレーターでステータスバーを含めた画面の表示崩れを確認したい場合、iOSのPlayer SettingsのTarget SDKをSimulator SDK にしよう。iOS
参照サイト参照サイト

・実機上で、UnityのConsole表示のようにDebug.Logの結果を表示できる
参照サイト参照サイト

・Androidで、ブレイクポイントを使用したデバッグを行う
参照サイト

・PCでRenderDocを使用して、レンダリングの過程、デバッグ、処理時間を詳しく見たい
参照サイト参照サイト参照サイト参照サイト

・Rider
高機能な有料のIDE
参照サイト参照サイト

・Roslyn Analyzersで、コーディング規約・非推奨APIなどといったカスタムルールを作成・検出し、品質を上げよう
参照サイト参照サイト参照サイト

~Unity Prpfile 始まり~

・なるべくビルドしてリリース端末でプロファイルをした方が、エディタ再生モードでプロファイルするより正確な情報が得られる
ただ、一々ビルドして確認だと時間がかかるので、実機でプロファイルした後で変更加えた箇所のパフォーマンスが改善されたかどうかをエディタでチェックするとイテレーションが早くなる
なおAutoconnect Profilerにチェック入れると、同じwifiに接続した状態であればiOS・AndroidとProfilerが自動で接続してテストできる
ちなみに、エディタ再生モードでプロファイルする際は、画面をマックスサイズにすると正確なデータをよりプロファイルできる
一方で、UnityProfileより正確なプロファイルするには、
iOS では、Instruments を使用
Android では、Android Profiler を使用
方が良い
参照サイト参照サイト参照サイト参照サイト参照サイト参照サイト

・Deepfileにチェックを入れて、UnityAPI(Updateなど)から呼びされたメソッドや、内部の処理の負荷を計測。
ただ、ゲームの実行速度が低下したりする。大きなゲームだと使用できない可能性もある
また、Call Stacksをオンにし、Related Dateに変更するとGC.Alloc、JobHandle.Complete、Native Allocationsであれば
コールスタックを見れるのでDeepfileが重い場合はこちらで確認するのも良い
Deepfileを使用しないで、メソッド内の特定の処理の負荷を計測したい場合は、CustomSamplerを使用すると計測できる
参照サイト参照サイト参照サイト

・Deep Profiling Supportにチェックを入れると、ビルドしたアプリでDeep Profilingができる

・Run In backgroundにチェックを入れると、ビルドしたアプリをバックグランド状態でもProfileできる

・Profiler (Standalone process) を使用した方が、Profiler使用するよりも正確なデータを取得できる
ただ、起動に時間が少しかかってしまう

・調査したいProfilerモジュールだけ選択した方がデータが正確になる

・プロファイルマーカー一覧
参照サイト

・ショートカット Ctrl+7

・File > Preferences > Frame CountでプロファイルするFrame数を指定できるが、数字が大きいとその分負荷がかかる

・ProfilerMarkerを使用して、任意の区間をプロファイラーで計測
参照サイト

・Editor AttachingとScript Debuggingをオフにすると、正確な測定値を得れる
参照サイト

・EditorOnlyを表示させたい場合は、Collapse EditorOnly Samples を無効
EditorOnly サンプルは、エディターのみの安全性チェックのためにのみ発生する Player Loop のサンプルである

・Time ms
アプリケーションが Job System やマルチスレッドレンダリングを使用する場合、現在選択しているスレッドで費やした時間しか含まれていないため、この情報は誤解を招く可能性があります。スレッドを変更するには、Hierarchy ペインの上部にある Thread ドロップダウンを選択します。
参照サイト

・GPU プロファイリングは、
AndroidはNVIDIA または Intel GPU を実行しているデバイスでのみ使用可
iOSは使用不可。代わりに XCode の GPU フレームデバッガー UI を使用
参照サイト

・Memory プロファイラーモジュールでアプリのメモリを把握する際は、なるべく実機につなげた状態でプロファイルした方が
正確なメモリ量を確認できる。Unityエディタ上でプロファイルすると他の処理でメモリが消費されてしまうためである
参照サイト

・実機で書き出したログデータをProfileで読み込ませることが可能
サイトの22分40秒~

・UserThreadに計測したい処理を、Timelineやhierarchyなどに表示できるになった。これで見やすくなる?
参照サイトの32分~

・Gfx.WaitForPresentが、ターゲットフレームを超えている場合フレームレートが落ちていることになる
例えば、60FPSのゲームだと、1フレーム当たり16msでフレームを生成しないといけないので、16msを超えてフレームを生成するとフレームレートが落ちているということである
そのフレームレートが落ちていることをProfiler上で簡単に確認する方法として、Gfx.WaitForPresentというのがありこちらは、CPUがGPUのフレームをレンダリングするの待機しているというマーカーなのでこちらの指標がターゲットフレームより大きければフレームレートが落ちていると確認できる。これは、つまりGPUかCPUの描画コマンド生成の問題があるということが分かる
参照サイトの15分19秒~、参照サイト参照サイト

・Gfx.WaitForCommandsが、ターゲットフレームを超えている場合フレームレートが落ちていることになる。こちらのGfx.WaitForCommandsは、CPUのレンダースレッドがGPUに描画コマンドを送るのを待機しているマーカーである。なのでこちらがターゲットフレームを超えている場合は、フレームレートが落ちているということになる。これはつまり、CPUが原因であり、プログラマーが書いたコードの処理に時間掛かっていたり、Unityエンジン側に時間がかかっているということである
参照サイト参照サイトの16分~

・プロファイラーの大まかな構成
Jobとは、メインスレッドの処理が圧迫しないように、他の処理をJobという別のスレッドで処理を行わせるスレッド。マルチコアでないとJobで処理はできない

Gfx.WaitForCommandsがターゲットフレームを超えていたら下記画像の赤枠の部分が問題があるので、Profiler(Profiler Analyzer)で原因を特定していく。
Gfx.WaitForPresentがターゲットフレームを超えていたらGPU側に問題があるので、
ProfilerやXcodeFrameDebuggerやRenderDocで(XcodeFrameDebuggerがおすすめ)原因を特定していく。主に見る観点として、ポリゴン数、フィルフレート、オーバードロー、シェーダーの負荷、デバイスの苦手な表現の有無などが挙げられる。参照サイトの1時間20分〜

CPU側からGPU側へ描画コマンドやリソースを送る箇所(上記画像だと、ゲームの描画をGPUへリクエストする)については、現在はDrawcallよりもSetPassCallを減らすことで負荷を削減できる。
具体的には、Frame Debuggerに表示されているパスを削減していくことでSetPassCallを削減できる。そのためには、SRPバッチングの適用、Sorting Priorityの調整、バッチングされない原因(Why this draw call can't be batched with the previous one)を取り除いていく。
参照サイトの1時間9分〜

・負荷のタイプ
負荷にも色々タイプが違うのでタイプに応じて対処していく必要がある
やたらと時間がかかる処理⇒処理を複数に分ける
やたら呼ばれている処理⇒処理する回数を減らす
その両方⇒どちらも対処する
参照サイトの30分30秒~

・何が重いのか確認
1.負荷が重い処理Top10を確認
2.瞬間か継続か
ロードするタイミングや大きなスパンで瞬間的に負荷がかかるような場合よりも、継続的に負荷がかかる箇所を解消していった方が良いかも?
3.負荷をselfを基準にして絞っていく
4.CustomSamplerでコード内のどこが悪いのか確認していく
参照サイトの40分から実践

・処理が軽いのに妙に時間がかかるケース
例えば、処理を非同期で実行。selfの時間は短いが、total的には長い時間がかかっている
参照サイトの36分〜

・メモリ使用量が多くて、ゲームが不正終了してしまう
①メモリリークが原因
Texture、Meshなどのアセットの使用量をメモリープロファイラーで計測し、継続的にメモリ容量が増えていたらメモリリーク可能性大
↓No
②大きいのはC#メモリ? or Unityメモリ?
 C#メモリの場合は、C#のスクリプトを見直す
ちなみにIn used(現在使用中)よりも、Reserved(予約)の方に注目したほうが良い
Reservedが多きすぎる場合、どこかでC#メモリが膨らんでいる可能性がある
特にファイル読み込みや通信のために一時的に大量のメモリを消費していないか確認すると良い
 Unityメモリの場合は、Detaiedビューや、パッケージのMemoryProfilerで各アセットの容量を確認。その際必要以上に大きいアセットは圧縮などして対処する。
また余計なアセットが読み込まれていないかも確認たり、必要であれば読み込むタイミングをずらしたりすると良い
※C#メモリ・・・
C#のスクリプト側で使用しているメモリで、GC対象(リーク可能性ない)
また、一度メモリをReservedしてから使うので、アプリを終了するまで返されない
Unityはパッキングを行わなのでメモリのフラグメントが起きる可能性がある
プロファイラの項目だとManaged HeapがC#メモリに当たる
※Unityメモリ・・・
Textutre、Mesh、アニメーションなどのアセットに占められるメモリ。リークする可能性がある
プロファイラの項目だとGraphics & Graphics Driver・Audio・Video・OtherがUnityメモリに当たる
参照サイトの9分10秒~

・ロード時間が長くて、ゲームのテンポが悪くなってしまう
①初期化処理が長い
スクリプト.Awake~というマーカで処理時間多くかかっているのであれば、初期化処理が原因である
②ロード時間が長い
CPUプロファイラーのグラフが一気に跳ねあがった箇所はロードしたタイミングのケースが多い
なので、無駄なものを読み込んでいないか?、データサイズが大きすぎないか?をチェック
Timeline上だと、MianTheredの他にLodingThreadでも読み込みを行っているのでそちらも見てみると良い
AssetBundleを使用している場合、予期せず重複したデータを読み込んでしまっていることがよくあるので注意
参照サイトの16分45秒~

・ゲームプレイ中に急に画面が一瞬固まり、プレイミスが起きてしまう
①GCが原因
CPUのプロファイラーのGCのみチェックし多く時間が取られている箇所で、GCAllocが多く割り当てられている箇所のC#スクリプトを修正していく
↓No
②ほかにロード等していないか?。他にも原因があるがそれらの詳しい内容は、下の「低いフレームレートでゲーム体験が劣化してしまう」を参考にする
参照サイトの22分~

・低いフレームレートでゲーム体験が劣化してしまう
CPUプロファイラを使用せずゲームロジックか描画負荷か見極めるときのテクニック
解像度を下げた状態で実機でテスト。もしそれでフレームレートが大幅に向上するなら描画が負荷原因。Screen.width/heigh、CameraのViewPortRect
①描画負荷が原因
CPUプロファイラのRenringのみチェックし計測し、時間が掛かっていたら描画負荷が原因
描画負荷が原因の際、考えるポイントを下記に記載する
1.余計な描画が入っていないか?
FrameDebuggerで最終的に画面に描画しないものが含まれていないか確認
2.Batch数、SetPass数が多くないか?
3.頂点数が多すぎないか?
4.描画面積が広くないか?(OverDrawしすぎていないか?)
透明な描画でも描画コストが発生する。また、ImageEffectは重いので注意
5.Shaderが重くないか?
Shaderないの計算が複雑になればなるほど、1ピクセルに描画するのにかかる時間が増えていく。
よくあるのが、描画面積の大きい地面・空などで重いShaderを使用していると大きな描画負荷になる。なので描画面積の大きいのShaderは軽めにするのも要検討。(Mobile系のShaderなど)
Shaderが重いかはどうかは、UnityProfilerよりも各プラットフォームのGPUProfierの方が正確に計測できる。
↓No
②ゲームロジックの負荷が原因
CPUプロファイラのRenringとVsync以外をチェックし計測し、時間が掛かっていたらゲームロジックの負荷が原因
C#スクリプトが負荷の場合は、CPUプロファイラーのBehaviourUpdateの各スクリプトで長い時間掛かっている箇所を探し、修正していく
Unityの処理が負荷の場合は、物理演算、UI処理あたりよくある負荷原因。
物理演算の場合は、CPUプロファイラーのPhysics.Processing、
UI処理の場合は、Canvas.SendWillRenderCanvasesを確認し、長い時間掛かっている箇所を探し、修正していく
※描画でもゲームロジックが原因でなくGameObjectが多すぎる原因もある。
参照サイトの22分~

・Profiling Core APIでより細かくProfierをカスタマイズできる。
例えば、ProfilerMarkerを使用すると、CustomSamplerで表示される情報よりもより細かい情報をProfilerに表示できる。例えばオブジェクトの数であったりを表示できる
また、ProfileCounterを使用すると、ある値のオリジナルのプロファイルグラフを作成できる。
参照サイトの12:50~

・CPU負荷とGPU負荷を、リアルタイムで表示させることができるFrameTimingManager
参照サイト参照サイト

・Time.realtimeSinceStartupを使用して、ある処理がどのくらいかかっているのか図る
参照サイトの13分~

・RecoderAPIを使用して、Profilerに載っている名前の処理時間、実行回数などを計測でき、画面に表示できる
参照サイトの18分~、参照サイトの15:25~

・あるスレッドが、どのスレッドに処理を投げていつ帰ってくるのかといった情報をTimeline上から視覚化できるようになった。
参照サイトの4:45~

・CustomSamplerで指定した箇所をクリックすると、ヒエラルキー上の対象オブジェクトが強調される。
参照サイトの6:15~

・ProfilerUnsafeUtilityを使用すると、CustomSamplerで指定した箇所の色を、カテゴリーの色と同じように表示できる。例えば、CPU UsageのPhysicsだとオレンジ色なので、Timeline上でオレンジ色で表示させることができる
参照サイトの7:30~

・ProfilerUnsafeUtilityを使用すると、Sample名だけでなく、キャラの数やロードしたパスなどの情報も表示できる
参照サイトの8:25~

・VSyncを無効化する
パフォーマンスの調査する際は、これがあるとどこに問題があるのか分かりづらいので
無効した方が調査しやす
チェックを外すか、Hierarchy ビューだとWaitForTargetFPSを無視すれば良い
参照サイト

・GCAllocがメインスレッド以外から発生する場合は、Unity Profiler には表示されない。 したがって、「GC Alloc」列を使用して、ユーザーが作成したスレッドで発生するマネージアロケーションを測定することはできません。そのため、デバッグのためにコードの実行を別のスレッドからメインスレッドに切り替えたり、BeginThreadProfiling API を使用して Timeline Profiler にサンプルを表示しないといけない。
参照サイト

・GCAllocは、ビルドされたものと、エディター上ではGCAlloc発生するしないがあるので、必ずターゲットデバイスの開発ビルドで検証したほうが良い
参照サイト

~Unity Prpfileまとめ 終わり~

・IDEを使用する際に必要なこと
Visual Studio、Visual Studio Code、JetBrains Riderを使用する際に必要なこと
参照サイト

・Unity で C# コードをデバッグ方法
PCとモバイルでデバッグする方法
参照サイト

・ログの出力する範囲を設定
ログの出力する範囲は、Stack Traceで設定できる。

None: Unity はスタックトレース情報を出力しません。
ScriptOnly: Unity はマネージコードのみのスタックトレース情報を出力します。これはデフォルトオプションです。
Full: Unity はマネージとアンマネージ、両方のコードのスタックトレース情報を出力します。
■プレイするユーザーにも影響する
このStack Traceの設定は、ゲームをプレイしているユーザーにも影響するので、アプリをビルドする際は負荷の高いFullなどは間違っても設定しないこと。
■マネージコードとアンマネージコード
マネージコードとは、 Unity で動作するマネージド DLL または C# スクリプトです。Unity に同梱されているスクリプト、独自に書いたカスタムスクリプト、アセットストアプラグインに含まれるサードパーティスクリプト、その他エンジン内で実行される C# スクリプトが該当します。

アンマネージコードは、ネイティブの Unity エンジンコード、またはマシン上やターゲットビルドプラットフォーム上で直接実行されるネイティブプラグインのコードを意味します。アンマネージコードは通常、C または C++ コードからコンパイルされます。ネイティブバイナリのオリジナルのソースコードを持っている場合のみ、アクセスすることができます。 通常、アンマネージコードのスタックトレースは、エラーの原因が自分のコードかエンジンコードか、またエンジンコードのどの部分にあるかを判断する必要がある場合にのみ使用します。
■ビルドしたアプリケーションの出力ログファイルはどこ?
こちらを参照
参照サイト

・Unity Test Framework
Unity Test Frameworkは、エディタ上でソースの単体テストを行えるライブラリーである。
参照サイト

・Xcodeフレームデバッガーのやり方と制限
参照サイト

・UnityのアプリをAndroidでテスト・デバッグする方法
①Android デバイスでテストする
②(アプリケーションのモバイル入力をテストするだけの場合は) Unity Remote を使用する
③(Android デバイスでの見た目をテストするだけの場合は) デバイスシミュレーター (Device Simulator) を使用する
詳しい内容は参照サイトを参照
参照サイト参照サイト参照サイト参照サイト

・AndroidのBuild SettingsのSymlink Sources
シンボリックリンク を作成して、Gradle プロジェクトが Unity プロジェクト内の Java および Kotlin ソースファイルを参照するようにするには、この設定を有効にしてください。これは、Java および Kotlin コードのテストとイテレーションを行う場合に役立ちます。
なぜなら、エクスポートされた Gradle プロジェクト内の Java および Kotlin ソースファイルに加えられた変更は、Unity プロジェクトを再エクスポートしても全て維持されるからです。
Export Projectを有効したときに、有効化される。
参照サイト参照サイト

・Build SettingsのDevelopment Build
このオプションを選択すると、条件付きコンパイルの DEVELOPMENT_BUILDを使用できる。
この設定はアプリケーションのテストを行いたい場合に使用してください。
参照サイト

・Build SettingsのAutoconnect Profiler
ビルドされたアプリケーションの実行時にプロファイラーをアプリケーションに自動的に接続するかどうかを指定します。
この設定は Development Build を有効にした場合のみ操作可能です。
なお、Deep Profiling Supportを有効にするとプロファイラーの Deep Profileを使用してプロファイルを行う。
参照サイト

Alembic
AlembicファイルをUnityで使用できるようになる
参照サイト

マネージヒープ
参照サイト

Write Permissionで、リソースファイルを外部ストレージ(SDカード)か内部ストレージを指定(Android)
SDカードを許可する場合、データを抜き差しできるので注意
参照サイト参照サイト参照サイト

Filter Touches When Obscuredをオンにして、タップジャック攻撃を防ごう
参照サイト参照サイト参照サイト

Scripting Define Symbolsで、共通のdefineを定義
参照サイト

null許容参照型を使用する
参照サイト

CS0169 と CS0649 の警告を無効化
参照サイト

Allow ‘unsafe’ Codeにオンにして、unsafeなコードを書く
参照サイト

Allow downloads over HTTP (nonsecure)をオフにすると、https1通信のみの通信となる。iOS
参照サイト参照サイト

Enable ProMotion Supportをオンにして、ProMotion 対応にする。iOS
参照サイト

Time Scaleでスローモーションや高速モーションの実装
大きくすると物理演算の回数も多くなりため負荷がかかるので注意
逆に、小さいと物理演算の精度がなくなる
参照サイト参照サイト

シーンテンプレートで効率的にゲーム開発しよう
参照サイト

セーフモードで、アップグレードした際のエラーを簡単に解消
参照サイト参照サイト

Unityのメモリ管理方法
参照サイト参照サイト

PlayerLoopでUnityが毎フレーム呼ぶ処理を無効にしたり、Update"前"に独自の処理を追加したり、順番を入れ替えたりする
参照サイト

Advertisement
広告をつけたい場合に使用する
Analytics Library
作ったゲームがどの程度遊ばれているのかをグラフとして見れる
参照サイト

Mobile Notifications
ローカルプッシュ通知を実装
参照サイト

Live Capture
バーチャルプロダクションをUnityエディタ上で行える

Input System
InputManegerの上位互換
参照サイト参照サイト参照サイト

In App Purchasing
ローカル開発環境での課金処理の実装、ライアント端末でのレシート検証
参照サイト

Collaborateでマージツール選択
参照サイト

修正差分を分かりりやすくする。Asset SerializationのForce Text
参照サイト

Localization
多言語化対応
参照サイト

・UnityのGC回りのメモ
ヒープ領域に、割り当てを行おうとして、領域がたりなかった場合ガーベッジコレクションが発動する。その際、ヒープ領域全体を一斉に調査するためヒープ領域が大きすぎるとその分時間がかかってしまう。また、パッキングが起きないためメモリの断片化が起きる。
ガーベッジコレクション行ってもなお、割り当てできない場合はヒープに拡張が行われるが、拡張される前の大体2倍になる。しかも、拡張されたヒープ領域は解放されることが稀である。
32bitのCPUの場合、マネージヒープが拡張と縮小を何度も繰り返すと最悪 OS によってプログラムが終了される可能性がある。
64bitのCPUの場合、このような事象は起きにくい。
ちなみに、現在のスマホは、Andoridの2018年以降の端末ならほとんどが64bit、iOSに至っては、iPhone5s以降から64bitである。
参照サイト参照サイト

・Unityのイベント関数
参照サイト参照サイト参照サイト

・NullReferenceException
NullReferenceExceptionは参照先がNullの場合に起こるエラーである。
以下のソースを実行すると、wibbleが存在しないのでNullReferenceExceptionエラーが発生する。

using UnityEngine;

public class Test : MonoBehaviour
{
    void Start()
    {
        GameObject go = GameObject.Find("wibble");
        Debug.Log(go.name);

    }

}

なので、NullチェックかTryCatchを行うのが良い。
参照サイト

・GameObjectクラス
GameObject.SetActive
→オブジェクトの有効・無効の設定

GameObject.activeSelf、GameObject.activeInHierarchy
→オブジェクトがアクティブかどうか

GameObjectUtility.SetStaticEditorFlags
→オブジェクトにグローバルイルミネーション、オクルージョン、バッチングを設定可能

GameObject.tag
→オブジェクトのTagを確認できる

GameObject.layer
→オブジェクトのlayerを確認できる

AddComponent <Type>
→オブジェクトにコンポーネント追加

Object.Destroy
→オブジェクトのコンポーネント削除

Transform.Find
→オブジェクトを検索

BroadcastMessage、SendMessage、SendMessageUpwards
→指定したすべてのメソッドを呼び出せる

GameObject.FindWithTag、GameObject.FindGameObjectsWithTag
→指定したオブジェクトのTagを検索できる
参照サイト

・オブジェクトから別のオブジェクトへの向きと距離

// プレイヤーの位置からターゲットの位置を指すベクトルを取得します
var heading = target.position - player.position;

ベクトルの向きだけが欲しい

// プレイヤーの位置からターゲットの位置を指すベクトルを取得
var heading = target.position - player.position;
var distance = heading.magnitude;
var direction = heading / distance; // 正規化された方向になります

参照サイト

・Vector3.Dot
Vector3.Dotは内積が行える関数。
これを利用して、単位ベクトルのベクトルを求められたり、ベクトルの角度を求められたり、表裏判定を行えたり、視線判定なども行える。
Vector3.Dotは、正弦を計算するよりも数学的に単純な演算です。そのため、状況によっては Mathf.Cos 関数やベクトルの magnitude 演算の代わりに使用することができます (全く同じことをするわけではありませんが、同等の効果が得られる場合もあります)。
しかし、Vector3.Dotで計算する方が、はるかに少ない CPU 時間で済むので、価値のある最適化になります。
参照サイト参照サイト

・Vector3.Cross
Vector3.Crossは2つのベクトルの、垂直ベクトル・法線ベクトルを取得できる。
参照サイト

・オイラー角をスクリプトで書く際の正しい方法
悪い書き方その1

// 回転スクリプトの誤り #1
// ここでの間違いは、クォータニオンの x 値を変更していることです。
//この値は角度を表すものではなく、求めている結果を生成しません
    
void Update () 
{
    var rot = transform.rotation;
    rot.x += Time.deltaTime * 10;
    transform.rotation = rot;
}

悪い書き方その2

// 回転スクリプトの誤り #2
// クォータニオンからオイラー値を読み取り、変更し、書き込みます。
// これらの値はクォータニオンから計算されるため、
// 新しい回転ごとにまったく異なるオイラー角が返される可能性があり、ジンバルロックが発生する可能性があります。
        
void Update () 
{
    var angles = transform.rotation.eulerAngles;
    angles.x += Time.deltaTime * 10;
    transform.rotation = Quaternion.Euler(angles);
}

正しい書き方

// オイラー角を正しく使用した回転スクリプト
// オイラー角をクラス変数に格納し、オイラー角として適用する場合にのみ
// 使用しますが、オイラー角にもどして読み取ることはありません。
        
float x;
void Update () 
{
    x += Time.deltaTime * 10;
    transform.rotation = Quaternion.Euler(x,0,0);
}

参照サイト

・Timeクラス
Time.time
→プロジェクトが再生を開始してからの時間 (秒単位) を返します。
※Time.timeScaleとTime.maximumDeltaTimeを考慮。考慮しないのは、Time.unscaledTime。これは、ゲームがスローモーションで再生されているときでも、固定の速度で応答する必要があるものすべてに便利です。この例として、UI インタラクションのアニメーションがあります。

Time.deltaTime
→最後のフレームが完了してから経過した時間 (秒単位) を返します。この値は、ゲームやアプリケーションの動作中の秒ごとのフレーム数 (FPS) により変化します。
※Time.timeScaleとTime.maximumDeltaTimeを考慮。考慮しないのは、Time.unscaledDeltaTime。これは、ゲームがスローモーションで再生されているときでも、固定の速度で応答する必要があるものすべてに便利です。この例として、UI インタラクションのアニメーションがあります。

Time.timeScale
→時間が経過する速度を制御します。この値を読み取ったり、設定して時間が経過する速さを制御し、スローモーションのような効果を生み出すことができます。

Time.fixedDeltaTime
→Unity の固定時間ステップのループの間隔を制御します (物理演算、決定論的な時間ベースのコードを書きたい場合に使用されます)。

Time.maximumDeltaTime
→上記の “deltatime” プロパティによってエンジンが時間の経過を報告する上限を設定します。
Unityエディター上だとTimeのMaximum allowed timestepで設定可能。
参照サイト

・可変フレームレート管理
品質設定 または Adaptive Performance パッケージ によって特に制約がない限り、Unity は可能な限り最速のフレームレートでゲームやアプリケーションを実行しようとします。
つまりアプリの負荷などによってFPSが変動してしまう可能性がある。
なので、Updateなどでオブジェクトが移動したり、回転したりするスクリプトを書く際は注意が必要である。

悪い書き方
これだと、100FPSと60FPSの場合、1フレームで移動できる距離が変わってしまって一定間隔で移動しているように見えないときがある

using UnityEngine;
using System.Collections;

public class ExampleScript : MonoBehaviour {
    public float distancePerFrame;
    
    void Update() {
        transform.Translate(0, 0, distancePerFrame); // this is incorrect
    }
}

正しい書き方
この場合だと、100FPSと60FPSでも1フレームで移動する距離は同じになるので、一定間隔で移動しているように見える

using UnityEngine;
using System.Collections;

public class ExampleScript : MonoBehaviour {
    public float distancePerSecond;
    
    void Update() {
        transform.Translate(0, 0, distancePerSecond * Time.deltaTime);
    }
}

参照サイト

・Mathfクラス
■三角法
Sin
Cos
Tan
Asin
Acos
Atan
Atan2
※PI は定数として利用でき、静的な値 Rad2Deg または Deg2Rad を掛けて、ラジアンと度の間で変換することができます。
■累乗と平方根
一般的な累乗と平方根の関数
Pow
Sqrt
Exp
また、 2 のべき乗関連の便利な関数もいくつか用意されています。これらは、2 のべき乗の値に制約されたり最適化されたりすることがよくある一般的なバイナリデータのサイズを扱う際に便利です (テクスチャの寸法など)。
ClosestPowerOfTwo
NextPowerOfTwo
IsPowerOfTwo
■補間
Lerp
LerpAngle
LerpUnclamped
InverseLerp
MoveTowards
MoveTowardsAngle
SmoothDamp
SmoothDampAngle
SmoothStep
※Vector クラス と Quaternion クラスには、それぞれ独自の補間関数 (Quaternion.Lerp など) があり、多次元の位置、方向、回転を補間することができます。
■値の制限と繰り返し
Max と Min
Repeat と PingPong
Clamp と Clamp01
Ceil と Floor
■対数
Log
Log10
参照サイト

・Randomクラス
■単純な乱数
Random.value は、
0.0 から 1.0 の間のランダムな 浮動小数点数 を生成します。一般的な使い方は、その結果を乗算して、0 から選択した範囲の数値に変換します。

Random.Range は、最小値と最大値の間 のランダムな浮動小数点数を生成します。指定した最小値と最大値が整数 (int) か浮動小数点数 (float) かによって、int または、float のいずれかを返します。
■円または球体内のランダムな点
Random.insideUnitCircle は、半径 1 の 円内でランダムに選択された点 を返します (ここでもその結果を乗算することで、任意の大きさの円内でランダムな点を得ることができます)。

Random.onUnitSphere は、半径 1 の 球体の内部でランダムに選択された点 を返します。

Random.onUnitSphere は、半径 1 の 球体の表面でランダムに選択された点 を返します。
■その他の種類の乱数値
ランダムな 回転 を生成するには、Random-rotation を使用します。

ランダムな 色 を生成するには、Random.ColorHSV を使用します。
参照サイト

・Debugクラス
Debug.Log("This is a log message.");
→コンソールにメッセージレベルのログを出力

Debug.LogWarning("This is a warning message!");
→コンソールに警告レベルのログを出力

Debug.LogError("This is an error message!");
→コンソールにエラーレベルのログを出力

なおこれらのログは、ログファイルにも出力される。
Debug.LogWarning("I come in peace!", this.gameObject);のように第二引数にthis.gameObjectを加えると、コンソールのでできたログをクリックすると該当オブジェクトがハイライトされる。

Debug.DrawLine
→線を描ける

参照サイト

・ExecuteInEditMode
ゲーム開始しなくても、Start()やUpdate()を実行できる。

・InitializeOnLoad
アタッチしなくても、Unityの起動時、シーンの起動時にメソッドを実行できる。
Unityの起動時、シーンの起動時に1回メソッド実行

using UnityEngine;
using UnityEditor;

[InitializeOnLoad]
public class Startup {
    static Startup()
    {
        Debug.Log("Up and running");
    }
}

Unityの起動時、シーンの起動時にずっとメソッド実行

using UnityEditor;
using UnityEngine;

[InitializeOnLoad]
class MyClass
{
    static MyClass ()
    {
        EditorApplication.update += Update;
    }

    static void Update ()
    {
        Debug.Log("Updating");
    }
}

参照サイト

・シリアライゼーションの規則
公式ドキュメントより抜粋。

・public であるか、または SerializeField 属性をもっていること。
・静的でないこと。
・const ではないこと。
・読み取り専用でないこと。
・シリアラル化可能なフィールド型であること。
・プリミティブなデータ型 (int、float、double、bool、string など) であること。
・Enum types (32 bits or smaller)
・固定サイズバッファであること。
・Unity の組み込み型 (例えば、Vector2、Vector3、Rect、Matrix4x4、Color、・・AnimationCurve) であること。
・Serializable 属性をもつカスタム構造体であること。
・UnityEngine.Object から派生するオブジェクトへの参照であること。
・Serializable 属性を持つカスタムクラスであること。(カスタムクラスのシリアライズ を参照)。
・上記のフィールド型の配列であること。
・上記のフィールド型の List<T> であること。

参照サイト

・条件付きコンパイル
条件付きコンパイルを利用して、プラットフォーム、Unityのバージョン、Mono・IL2CPP、.NET ごとなどにコンパイルしそれぞれ処理を分けれる。
以下がソースである。

using UnityEngine;

public class Test : MonoBehaviour
{
	public GameObject test1;
	public GameObject test2;
	private void Start()
	{
		//ゲームするプラットフォームがWindowsであるとき
#if UNITY_STANDALONE_WIN

		Instantiate(test1);

#endif

		//Unityエディタ上で再生したとき
#if UNITY_EDITOR_WIN

		Instantiate(test2, new Vector3(0, 2, 0), Quaternion.identity);

#endif


	}
}

Unityエディタ上の結果

Windows用にビルドした結果

プラットフォームごとに処理が分けられているのが分かる。
なお、Unityが初めから用意してくれているスクリプトシンボル以外にも、自分でカスタムスクリプトシンボルを作成できる。
Other SettingsのScript Compilationで可能である。

以下がソースである。

using UnityEngine;

public class Test : MonoBehaviour
{
	public GameObject test1;
	public GameObject test2;
	public GameObject test3;
	private void Start()
	{
		//ゲームするプラットフォームがWindowsであるとき
#if UNITY_STANDALONE_WIN

		Instantiate(test1);

#endif

		//Unityエディタ上で再生したとき
#if UNITY_EDITOR_WIN

		Instantiate(test2, new Vector3(0, 2, 0), Quaternion.identity);

#endif
		//自分でカスタムしたスクリプトシンボル
#if Test

		Instantiate(test3, new Vector3(2, 0, 0), Quaternion.identity);

#endif


	}
}

結果がこちらである。

確かにカスタムしたスクリプトシンボルが正しく機能しているのが分かる。
参照サイト参照サイト

・プラグイン
Unity では、通常は スクリプト を使用して機能を作成しますが、Unity の外で作成したコードを プラグイン 形式で加えることもできます。Unity で使用できるプラグインには、以下の 2 種類があります。
①マネージプラグイン
Visual Studio などのツールで作成できる マネージ .NET アセンブリ です。これらは .NET コードのみを含むため、.NET ライブラリがサポートしない機能にはアクセスできません。
②ネイティブプラグイン
プラットフォーム固有のネイティブコードライブラリです。OS 呼び出しやサードパーティコードライブラリなど、Unity では利用できない機能にアクセスすることができます。
参照サイト参照サイト

・Unity as a Library
Unity as a Libraryとは、Unity以外で作成したアプリ上で、Unityで作成したゲームをプレイできるような技術。
例えば、iOSアプリを作成する際はSwiftというフレームワークで作成することがあるが、それとUnityで作成したゲームなどを合体できる。
Mirrativなどでも使用されている。
ただいくつか制限があるので参照サイトを参照
参照サイト参照サイト参照サイト

・ディープリンク
ディープリンクとはアプリケーションの外にあって、ユーザーをアプリケーション内の特定の場所に遷移させるURLリンクです。
ディープリンクを使用すると、WebページでAppStoreとかGooglePlayStoreのアイコンがあってタップすると、アプリがインストール済みならアプリ起動・未インストールならストアへ飛ばされるみたいなことがC#スクリプトで簡単にできる。
参照サイト参照サイト参照サイト

・モバイルデバイスの入力処理全般
参照サイト

・iOSで、コントローラーで入力処理
参照サイト

・Input FieldコンポーネントのKeyboard Typeで、スマホ上でテキストを入力する際のIMEを制御する。
参照サイト

・Internet Access
Player SettingsのInternet Accessで、ネットワークを利用するのをネットワーク API を使用している場合か、必ずネットワークを利用かを設定する、
参照サイト

・Low Accuracy Location
Android 位置情報 API で低精度の値を使用するには、このオプションを有効にします。
参照サイト

・Active Input Handling
Input ManagerかInput Systemかその両方を選択できる。
参照サイト

・キーストア関連
参照サイト参照サイト

・バイブレーション実装
参照サイト参照サイト

・デバイス固有のプロパティにアクセス
■SystemInfo.deviceUniqueIdentifier
常に ANDROID_ID の md5 を返します。詳細については、Android デベロッパードキュメントの ANDROID_ID を参照してください。
■SystemInfo.deviceName
デバイス名を返します。Android デバイスの場合、Unity は安全なシステム設定から device_name と bluetooth_name を読み取ろうとします。これらの文字列に値がない場合、Unity は <unknown> を返します。
■SystemInfo.deviceModel
デバイスモデルを返します。多くの場合、これには製造社名とモデル番号が含まれます (例えば、“LGE Nexus 5 や ”SAMSUNG-SM-G900A" など)。
■SystemInfo.operatingSystem
オペレーティングシステムの名前とバージョンを返します。
参照サイト参照サイト

・Android のプラグインの作成と利用
プラグインを使って、リソースを配布し、Unity の外部で作成された Java や C++ コードを C# スクリプトから呼び出しすることができます。これにより、他の方法では Unity で使用できないサードパーティのコードライブラリや OS の呼び出しなどの機能にアクセスできます。
詳しい内容は参照サイトを参照
参照サイト

・Androidのデバイスの機能と権限
アプリケーションは、デバイス上のプライベートデータにアクセスしたり、内蔵マイクやカメラなどのデバイス機能を使用したり、アプリケーションのサンドボックス外でデバイスと相互作用したりするためには、デバイスのユーザーからの許可 (権限) を得る必要があります。
詳しい内容は参照サイトを参照
参照サイト

・サポートされる iOS バージョン
参照サイト

・Unity Distribution Portal
様々なストアにゲームを配信できる

・Remote Config
ストアにリリースせずともプログラム内の値への変更と、強制アップデート機能
参照サイト

・iOSアプリを端末にインストールしたりAppStoreにアップロードするときに必要なファイルをUnity上から設定
参照サイト参照サイト

・Override Default Package Nameにチェックを入れないとビルド時にエラーが出る
参照サイト

・aabファイルをアップロードした際、「バージョン コード1のAPKまたはAndroid App Bundleがすでに存在するため、別のバージョン コードを使用する必要がありあます。」と出た時の対処
参照サイト参照サイト参照サイト

・Target Architecturesで、Androidの64 bit対応
Target Architecturesは、CPUのアーキテクチャが設定できる。
ARM64はARM64
ARMv7はARM32
x64はIntel/AMD64
x86はIntel/AMD32
今のAndoroidは、ARM64とARM32が主流なのでこの両方をチェックしておけばOK
参照サイト参照サイト参照サイト

・Install Locationで、アプリのインストール先を指定
参照サイト参照サイト

・Unityのデータを保存する先。ストア申請にも影響してくる(iOS)
参照サイト参照サイト

・Android アプリケーションのサイズ制限
AndroidのアプリをGooglePlayなどでリリースする際は、アプリケーションの制限があるので、アセットを分割しないといけないケースが出てくる。
アプリのサイズ制限を超えそうな場合以下の方法を実施する必要がある。

公開形式 アセット分割ソリューション
APK APK 拡張ファイル
Android App Bundle (AAB) Play Asset Delivery

なお、GooglePlayはAABでないとダメ
それぞれの実際のやり方はなどは、参照サイトを参照
参照サイト

・Androidのアプリサイズ150以上だとGooglePlayにリリースできないので、
Play Asset Delivery(PAD)を使用してリリース
参照サイト参照サイト参照サイト参照サイト

・GooglePlayStoreに公開するために必要なAPK(ABB)ファイルの作成方法。Project KeystoreとProject Key
参照サイト参照サイト参照サイト

・Android マニフェスト、Gradle テンプレート、Proguard ファイルを追加でカスタマイズする
Custom Main Manifest、Custom Launcher Manifest、Custom Main Gradle Template、Custom Base Gradle Template、
Custom Gradle Properties Template、Custom Proguard File
参照サイト

・Xcode上でSiginingのTeamを自動的に設定できるAutomatically Sign
参照サイト参照サイト

・スマホのカメラを使用するには、Camera Usage Descriptionに何かしらの文章を記載する必要がある。
Camera Usage Descriptionは、iOSのPlayer Settingsに項目でデバイスのカメラにアクセスする理由を入力できる。
参照サイト参照サイト

・iOSのPlayer SettingsのMicrophone Usage Description
デバイスのマイクにアクセスする理由を入力します。
参照サイト

・iOSのPlayer SettingsのLocation Usage Description
デバイスの位置情報にアクセスする理由を入力します。
参照サイト

・iOSのPlayer SettingsのUse On-Demand Resources
オンデマンドリソースを使用するには、このオプションを有効にします。
オンデマンドリソースはAppleにビルドを提出する段階で画像などのアセットをサーバーに登録しておき、アプリ内からリアルタイムに取得するという仕組みらしい。
参照サイト参照サイト

・iOSのPlayer SettingsのAccelerometer Frequency
加速度センサーをサンプリングする頻度を定義できる。
周波数は15Hz、30Hz、60Hz、または100Hzに設定できます。
パフォーマンスを向上させるには、より低い周波数を使用します。
参照サイト

・iOSのPlayer SettingsのSupported URL schemes
サポートされている URL スキームのリスト。
新しいスキームを追加するには、Size プロパティの値を増やし、表示される新しい要素ボックスにロードするアセットへの参照を設定します。
参照サイト

・iOSのPlayer SettingsのRequires Persistent WiFi
Wi-Fi 接続を要求するには、このオプションを有効にします。
これにより、アプリの実行中もアクティブな Wi-Fi 接続が維持されます。
参照サイト

・Player SettingsのRequires Target Device
アプリケーションがターゲットにするデバイスを選択します。
例えば、スマホだけ、タブレットだけ、その両方などが選択できる。
参照サイト参照サイト

・iOSのPlayer SettingsのRequires ARKit support
これを有効にすると、App Store に公開するときにアプリを iPhone 6s/iOS 11 以降のデバイスに制限します。
参照サイト

・iOSのPlayer SettingsのAutomatically add capabilities
このオプションを有効にすると、Unity は entitlements.plist ファイルを生成し、アプリケーションが実装する iOS API (例えば Game Center や Notifications) の機能を加えます。
参照サイト

・iOSのPlayer SettingsのDefer system gestures on edgesとHide home button on iPhone X
iPhone XのホームUIの表示を制御できる。
Hide home button on iPhone Xだと、タップせずしばらく放置すると消えるが1回フリックでアプリ停止してしまう。
Defer system gestures on edgesだと、消えずにうっすら残り、2回フリックでアプリ停止する。
参照サイト参照サイト

・Target minimum iOS Versionで、iOSの最低バージョン指定
これで指定したバージョンより低いと、アプリを使用できなくなるのでどこまでのデバイスをターゲットにする際は慎重に
参照サイト参照サイト参照サイト

・iOS 14 Advertising Support
企業がIDFAを取得するためには、ユーザの許可を取らないといけないがそれを実装する
参照サイト

・AndroidのGradle
Gradle は、多くのビルドプロセスを自動化し、一般的なビルドエラーの多くを防止するビルドシステムです。Unity はすべての Android ビルドに Gradle を使用します。
詳しい内容は参照サイトを参照
参照サイト参照サイト

・Android 用のアプリを作成する際の環境設定
Android 用 Unity アプリケーションの作成にあたっては、Android をサポートするように Unity プロジェクトを設定する必要があります。
以下が必要である。
①依存関係のインストール(Unity Hubで可能)
Android Build Support
Android SDK & NDK Tools
OpenJDK

②Target API Levelを設定
PlayerのTarget API Levelを設定する
参照サイト

・iOS 用のアプリを作成する際の環境設定
iOS 用の Unity アプリケーションを作成するには、まず iOS をサポートするように Unity プロジェクトを設定する必要があります。
以下が必要である。
①依存関係のインストール(Unity Hubで可能)
iOS Build Support
②Xcode または Unity Cloud Build
ローカルでiOSアプリケーションをビルドしたい場合は、Xcode をインストールする必要があります。Xcode は macOS でのみ利用可能です。そのため、開発マシンが macOS を実行しない場合、アプリケーションをローカルでビルドすることはできません。ただし、Unity Cloud Build はアプリケーションをビルドしてくれるので、macOS でないマシンでも iOS アプリケーションを開発することができます。

なお、iOS デバイスでビルドをテストするには、無料の Apple ID が必要です。ただし、ゲームを App Store で配信したり、Game Center や アプリ内課金などのサービスを使用したりするには、Apple Developer Program に登録する必要があります。
参照サイト

・Player SettingsのWarn about App Bundle size
AABのサイズが特定のしきい値を超えたときに警告を受け取るには、このオプションを有効にします。
参照サイト

・Android 用のビルドとアプリ公開
参照サイト

・iOS 用のビルドとアプリ公開
参照サイト

・AndroidのBuild SettingsのExport for App Bundle
エクスポートされた Gradle プロジェクトが Android App Bundle としてビルドされるように設定するかどうか指定します。
この設定は、Export Project を有効にした場合にのみ表示されます。
参照サイト

・AndroidのBuild SettingsのCreate symbols.zip
Unity がアプリケーションをビルドする際に、どの方法で シンボルパッケージ を生成するかを指定します。
■Disabled
Unity はシンボルパッケージを生成しません。
■Public
Unity はアプリケーション用に パブリックシンボル パッケージを生成します。
■Debugging
Unity はアプリケーション用に デバッグシンボル パッケージを生成します。

なお、シンボルとはアプリケーションのデバッグを支援するために、Unity のネイティブライブラリのシンボルファイルを含むパッケージを生成することができます。シンボルファイルには、アクティブなメモリアドレスをメソッド名などの使用可能な情報に変換するテーブルが含まれています。この変換プロセスをシンボル化と呼びます。シンボルパッケージを Google Play Console にアップロードすると、Android Vitals ダッシュボードで人間が読めるスタックトレースを表示できます。
ストアでアプリを公開するときは、必ずPubliしないといけない。
参照サイト参照サイト

・iOS アプリをビルドする方法
参照サイト参照サイト

・iOSのPlayer SettingsのDebugging and crash reporting
Debugging and crash reporting の設定を使用して、アプリケーションのパフォーマンスに関するデータを収集し、クラッシュをトラブルシューティングします。
■Enable Internal Profiler (Deprecated)
この機能は非推奨で、Unity の将来のバージョンで廃止される予定です。代わりに Profiler ウィンドウ を使用してください (Window> Analytics> Profiler)。
プロファイラーはアプリケーションのパフォーマンスデータを収集し、レポートをコンソールに出力します。レポートには、各 Unity サブシステムが各フレームで実行に要したミリ秒数が 30 フレーム平均で表示されます。
■On .Net UnhandledException
.NET の未処理の例外が発生したときに実行するアクションを選択します。オプションは Crash (アプリケーションがクラッシュしてクラッシュレポートを生成します - ユーザーはそれを iTunes に送信してクラッシュのトラブルシューティングに使用できます) と Silent Exit (アプリケーションはエラーなしで終了し、クラッシュレポートを生成しません) があります。
■Log Obj-C Uncaught Exceptions
このアクションを有効にすると、Unity は Objective-C Uncaught Exception 情報をコンソールに出力します。
■Enable Crash Report API
カスタムクラッシュレポーターがクラッシュをキャプチャできるようにします。スクリプトを使用して CrashReport API経由でクラッシュログにアクセスできます。
参照サイト

・iOSの機種判定
iOS.DeviceGenerationで可能
参照サイト

・ReplayKit を使用して、ゲームのオーディオと動画を記録し、デバイスのマイクとカメラから取り込んだオーディオと動画の解説を加えることができます。
参照サイト

・App Store でリリースした後にアプリケーションのサイズが増加したのはなぜか
アプリをパブリッシュするときに App Store では最初にバイナリファイルを暗号化して zip で圧縮します。暗号化によってコードセグメントがよりランダムになり、圧縮の条件が悪くなるため。
参照サイト

・UnityでのiOS 承認
Apple のオペレーティングシステムは、アプリケーションが機密情報やデバイス機能にアクセスする前に承認をリクエストすることを義務付けています。アプリケーションがデバイスの カメラ、マイク、位置情報などの機能にアクセスする必要がある場合は、必ず、デバイスのユーザーが、アプリケーションにアクセス許可を与える必要があります。
そのやり方は参照サイト参照
参照サイト

・Social API
Social APIは以下の機能を備えている。
①ユーザープロファイル
②フレンドリスト
③ゲーム実績( Achievements )
④統計/ランキング( Statistics / Leaderboards )
参照サイト

・iOSのトラブルシューティング
iOS では、ゲームが Unity エディター上では完璧に動作するのに、その後、実際のデバイス上で動作しない、起動しないなどの状況が発生することがあります。
代表的なトラブルシューティングを記すが、解決方法は参照サイト参照
■ゲームがしばらくして応答を停止し、Xcode がステータスバーに interrupted (中断) と表示する
■Xcode コンソールが "Program received signal: SIGBUS” または EXC_BAD_ACCESS エラーを表示する
■外部ライブラリが Unity iOS アプリケーションにリンクされているとき EXC_BAD_ ACCESS が発生する
■Xcode のコンソールに “WARNING -> applicationDidReceiveMemoryWarning()” が表示され、その後すぐにアプリケーションがクラッシュする
■ゲームが Xcode から起動したときには正しく実行されるが、デバイス上で手動で起動すると最初のレベルのロード中にクラッシュする
■Xcode Organizer コンソールのメッセージに “killed by SpringBoard” が含まれる
■Type.GetProperty() または Type.GetValue() によってデバイスのクラッシュが発生する
■エラーメッセージ “ExecutionEngineException: Attempting to JIT compile method ‘SometType`1<SomeValueType>:.ctor ()’ while running with –aot-only.” を表示してゲームがクラッシュする
■System.Security.Cryptography とマネージコードストリッピングの組み合わせを使用するとき、さまざまなクラッシュがデバイス上で発生する
■“Ran out of trampolines of type 0/1/2” ランタイムエラー
■Xcode Unity iOS をアップグレードした後、ランタイムエラーメッセージ “You are using Unity iPhone Basic. You are not allowed to remove the Unity splash screen from your game” (Unity iPhone Basic を使用しています。ゲームから Unity のスプラッシュスクリーンを削除することはできません) が表示される
■WWW のダウンロードが Unity Editor と Android 上では正常に動作するが、iOS 上ではうまくいかない
■スクリプトからコールしたネイティブ関数を経由して Cocoa を使用した際に “PlayerLoop called recursively!” (PlayerLoop が再帰的に呼ばれてます) エラーが発生する
■プロファイラーやデバッガーで iOS デバイス上で実行しているゲームを見ることができない
■DLL が見つからない
■Xcode デバッガーコンソールが –aot-only で実行時に以下を出力する: ExecutionEngineException: Attempting to JIT compile method ‘(wrapper native-to-managed) Test:TestFunc (int)’
■Xcode が以下のコンパイルエラーを表示: “ld : unable to insert branch island. No insertion point available. for architecture armv7”, “clang: error: linker command failed with exit code 1 (use -v to see invocation)”
参照サイト

・iOS のクラッシュバグのレポート方法
参照サイト

Discussion