講演ファイル(PDF)

Unity上級者を目指すなら
知っておくべき
デバッグテクニック集
荈䊹稱➜
名前:山村達彦
役職:フィールドエンジニア兼
エバンジェリスト
趣味:ブログ
自転車(new)
ブログ:テラシュールブログ
Twitter:@tsubaki_t1
•
•
•
Unity上級者へ至る道とは?
Unity上級者とは何か
コードが書けて、設計もできて、3Dに対する知識もあって、
各プラットフォームの知識もあって、運営もできて
UnityのAPIまわりとバッドノウハウを完璧に把握して
モデルもシェーダーも作れて作曲も2D・3D・VRが出来て、経営に詳くて…英語も出来る
♳秷罏‫פ‬荚‫׷‬銲㔓‫
א♧ך‬
չ㉏겗‫׾‬鍑寸‫׷ׅ‬䪮腉պ
問題を見つける
問題を回避する
問題を起こさず実現する
չ2㉏겗‫ג׏‬պ
「A:ああ!」
今回は所謂「バグ」を指す。
バグは「思い通りに動かない事」を指す。
•
•
バグとは何か?
‫ؚغ‬䙼‫׋׏‬鸐‫✲ְזַ⹛ח׶‬
1. 操作に反応しない
2. モデルが変な動きをする
3. 入力した情報が反映されない
4. 計算結果が思ってたのと違う
5. 効果の影響範囲がおかしい
6. 通らないはずの処理が実行された
7. 操作に対して向きが変
ֿ‫ַׅדؚغכ׸‬
多分バグです。
‫‪銲㔓麦‬ךؚغ‬
‫ؚغ׷‪⣛‬חيؤٔ؞ٕ‪،‬װس‪٦‬؝أ‪٦‬ا •‬
‫ؚغ׷‪⣛‬חة‪٦‬ر •‬
‫ؚغ׷‪⣛‬ח‪• 乼⡲‬‬
‫ؚغך‪04‬װؙ‪ٙ٦‬ي‪ٖ٦‬ؿ •‬
‫ا‬٦‫؝أ‬٦‫س‬涸‫㉏ז‬겗
• 想定した順番で処理が通らない
• 計算結果が思ってたのと違う
• 変なタイミングで処理が呼ばれる
• 実行順番が思ってたのと違う
• 例外が出る
‫‪㉏겗‬ז‪涸‬ة‪٦‬ر‬
‫ְזֻ׃‪铣鴥⯓ָ姻‬ךة‪٦‬ر •‬
‫׷ָ֮׶‪铎‬חزحو‪ؓ٦‬ؿ •‬
‫׷ָ֮‪㉏겗‬ח‪瘝‬ـعٖف‪٦ٝծ‬ء •‬
‫أى‪• 鏣㹀‬‬
乼⡲涸‫㉏ז‬겗
• 分かり難いUI表現
• 複数回入力
• 入力項目(表記)のミス
• 機材の故障
‫ٖؿ‬٦‫ي‬ٙ٦‫װؙ‬04‫ח‬⣛‫㉏׷‬겗
• Unityによる問題
• OSによる問題
• プラットフォームによる問題
•
•
バグを直すためには?
‫ךؚحغر‬然钠䩛갫
1. バグを正しく定義する
2. バグを再現する
3. バグが発生する箇所を見つけ出す
4. 問題を修正する
‫׷ׅ‪ֻ㹀纏‬׃‪姻‬׾ؚغ‪‬‬
‫‪։‬ׅדؚغ‪ְծ‬כ‪ַխ։‬ׅדؚغכ׸ֿ •‬
‫‪ַ‬ׅד‪⹛⡲‬זֲ״ךוכ‪ְ⹛⡲‬׃‪• 姻‬‬
‫ⱄ׾ؚغ‬植‫׷ׅ‬
• バグを再現させて、
再現する手順を確立する
• 再現する条件は、例えば…
• 特定の条件で必ず再現する
• タイミングが重要
• 起動時間や回数が必要
• 負荷が高い時に起こる
‫׾ؚغ‬穾‫׶‬鴥‫׬‬
• バグが「再現しない」状態と
「再現する」状態を比較する
• 問題が無い要素は消していく
• リソースを差し替える
• パラメータを変えてみる
• 環境を変えてみる
• タイミングや負荷を変える
‫חٕف‪ٝ‬ءגְ‪ꤐ‬׶《׾ⴓ‪㉏겗搀ְ鿇‬‬
‫
׾‪٥Ⳣ椚‬ز‪ٝ‬ط‪٦‬ه‪ٝ‬؝‪٥‬زؙؑآـؔז‪• ♶銲‬‬
‫׷ׅفحؗأ‬
‫
‪ծ‬ל׸֮דך׷ָ֮⻉‪㢌‬ח‪㉏겗‬ח‪ꥷ‬׋׃חٕف‪ٝ‬ء •‬
‫׷ָ֮‪㉏겗‬ח‪銲稆‬׋׃‪ַ嶊‬ؚ‪ٝ‬ى؎ة‬
然钠‫ך‬崧‫׸‬
乼⡲倯岀‫ךأ؎غرװ‬䱸竲‫׾‬然钠‫׷ׅ‬Ⰵ⸂‫㉏ך‬겗
‫ًٓػ‬٦‫׾ة‬䊴‫׃‬剏ִ‫׷׫ג‬‫ر‬٦‫㉏ךة‬겗
• データの参照先が間違っていて、データ差し替えても意味ないケースも
‫ךيؚٓٗف‬崧‫׾׸‬然钠‫׷ׅ‬‫ا‬٦‫؝أ‬٦‫㉏ךس‬겗
04‫׾‬䊴‫׃‬剏ִ‫׷׫ג‬ٕ٦ٕ‫㉏ך‬겗
穾‫׶‬鴥‫ך׫‬䩛갫
㉏겗ワ鴟‫؝ך‬٦‫כس‬ㄎ‫ַ׷ְג׸ל‬
‫ًٓػ‬٦‫כة‬姻‫ְַ׃‬
㉏겗涪欰儗‫כ⦼ך‬姻‫ְַ׃‬
Ⳣ椚‫ך‬㹋遤갫殢‫כ‬姻‫ְַ׃‬
䒭‫כ‬姻‫ְַ׃‬
㉏겗ワ鴟‫؝ך‬٦‫כس‬ㄎ‫ַ׷ְג׸ל‬然钠
• ログを表示するコードを記述
• Debug.Logを使用する
• 呼び出し元オブジェクトを探しやすい
• コンソールをPINで表示出来る
• ログを一括で停止させる
「Debug.logger.logEnabled = false;」
‫ًٓػ‬٦‫כة‬姻‫ְַ׃‬
SceneやPrefabといったメタデータ上で、
正しい項目が設定されているか。
• 参照がmissingやnull
• 間違った参照、URL、キー
• 想定範囲外のパラメータ
• Inspectorに入力した値は、
ソースコードより優先される
‫ًٓػ‬٦‫כة‬姻‫ְַ׃‬然钠
• Assertを使用する
• IsNotNullでもインスタンスが無い場合
があるので注意
• Unityのシリアライズ可能な(Inspectorに
露出してる)項目の値がおかしい場合、
大体ここが問題
‫׷׸ַ‪ꤐ‬׶《דسٕؽأ‪ٔٔ٦‬כ‪"TTFSU‬‬
˟*T/PU/VMM‫؎׮ד‬ٝ‫ةأ‬ٝ‫ָأ‬剣‫׷‬㜥さ
• $PNQPOFOU‫(װ‬BNF0CKFDU‫כ‬ծ*T/PU/VMM‫؎׮ד‬ٝ‫ةأ‬ٝ‫׷ָ֮أ‬㜥さָ֮‫׷‬կ
‫؝‬ٝ‫ه‬٦‫ط‬ٝ‫؜װز‬٦‫ؒכزؙؑآـؔي‬ٝ‫آ‬ָٝ؎ٝ‫ةأ‬ٝ‫׾أ‬盖椚‫׃‬ծ
խ$‫⿫כד‬撑‫⥂׾‬䭯‫דך׷ְג׃‬ծⰻ鿇涸‫כח‬/VMM‫⿫׮ד‬撑ָ婍‫
׭׋׷ג׏‬
խ⚥魦‫כ‬/VMM‫ָ׌‬/VMM‫ⴻהְזכד‬㹀ׁ‫׷ָ֮✲׷׸‬
• ؔ‫כزؙؑآـ‬ծ
*T5SVFPCKOVMM
‫זֲ״ך‬䒭‫׷ؙׅحؑثד‬
‫ًٓػ‬٦‫כة‬姻‫ְַ׃‬然钠
TestRunnerでテストを書く
• プロジェクト内のパラメータを確認する
手っ取り早い方法の一つ
• TestRunnerは開いてるシーンで実行
Ⳣ椚㹋遤儗‫ָ⦼ך‬姻‫ְַ׃‬然钠‫׷ׅ‬
• Debug.LogやAssertで値を觀察する
• リッチテキストで表現を切替
• 大量にある場合、ログファイルを見る
• Collapseはログ出力箇所と内容で纏まる
• 流れを見る場合、Collapseはoffに
Ⳣ椚㹋遤儗‫ָ⦼ך‬姻‫ְַ׃‬然钠‫׷ׅ‬
• デバッガで確認
• 処理を止めて確認
• スコープ外の値も確認可能
• ブレークポイントの条件を指定
• IL2CPP環境下では
ネイティブのデバッガを使う
Ⳣ椚㹋遤儗‫ָ⦼ך‬姻‫ְַ׃‬然钠‫׷ׅ‬
• デバッガ処理中は、例外発生時に処理を止めてくれる
(Error PauseをONにしてると効かなくなるので注意)
• ブレイク中はUnityエディタを操作することは出来ない
Ⳣ椚㹋遤儗‫ָ⦼ך‬姻‫ְַ׃‬然钠‫׷ׅ‬
Immediateで別のAPIを呼ぶ
‫ًٓػ‬٦‫כة‬姻‫ְַ׃‬然钠
• EditorUtility.InstanceIDToObject
で、インスタンスIDからオブジェクトを
取得
• 正しいリソースが取れてるか確認
• DebugのPINを使用しても良い
• https://gist.github.com/tsubaki/
9610d757aecee20c48e616abff0888b3
‫ֽⴓְ‪⢪‬ך*‪٥*.(6‬ؚٗהؖحغر‬
‫*‪0O(6‬װ‪%FCVH-PH‬ל׵זة‪٦‬رך‪• 㣐ꆀ‬‬
‫ؖحغر׵׋׭‪鴥‬׶‪• ㉏겗ָ穾‬‬
Ⳣ椚㹋遤儗‫ָ⦼ך‬姻‫ְַ׃‬然钠‫׷ׅ‬
• OnGUI(IMGUI)を使用する
• GUILayoutで上から順に描画
• Inspectorのデバッグモードで確認する
Ⳣ椚㹋遤儗‫ָ⦼ך‬姻‫ְַ׃‬然钠‫׷ׅ‬
• Gizmoを利用する
• 影響範囲や方向等を表現
• Handle
• テキストやステータスを画面に表示
• エディタ用APIなので、#ifで隔離が必要
㹋遤갫䎷‫כ‬姻‫ְַ׃‬
• スタックトレースで確認
• 処理の実行順番が表記される
• SendMessage等のテキスト経由でも
表示される
• 別スレッドから呼び出した場合、
スタックトレースがログに含まれない
(FULLで出力した場合は見れる)
㹋遤갫䎷‫כ‬姻‫ְַ׃‬
• デバッガのステップ実行
• 1秒ずつ進める
䒭‫כ‬姻‫ְַ׃‬
• ‫ا‬٦‫؝أ‬٦‫׾س‬然钠‫׃‬ծJG勴⟝‫װ‬،ٕ‫
ָيؤٔ؞‬
姻‫ְַ׃‬嗚鏾‫׶׋׃‬ծ‫׾زأذ‬剅ֻ
勴⟝䒭ָ醱꧟‫ז‬㜥さծ醱侧‫ך‬銲稆‫ֽⴓח‬-PH‫דؖحغرװ‬然钠‫׷ׅ‬
• "1*‫ך‬⢪ְ倯‫כ‬姻‫ְַ׃‬
FHչӍպ‫ך‬Ӎָ‫⹛זֲ״ךו‬⡲ַⴓַ‫ל׸ֽז׵‬ծ
姻鍑‫⥂׾‬鏾‫⳿כ✲׷ׅ‬勻‫ְז‬
‫⟃׸׉‬㢩‫㉏ך‬겗
• OSを変えた時に正しく動作する?
• エンジンのバージョンでバグる?
• ILが正しく出力されていない?
• 影響範囲が大きいので
バッドノウハウ探した方が無難な事も
‫
דؙحغس‪٦‬؍ؿכؚغך‪6OJUZ‬‬
‫‪կ‬ׅת׶ַ⸔ה׷ֽ‪㜠デ갥‬‬
バグは
「ソースコード」「データ」
「ルール」「入力」から来る
検証は「入力」「データ」「ソースコード」「ルール」が楽
検証は問題のある所を探す
「呼ばれてるか?」「値は正確?」
「想定の場所から呼ばれてる?」「処理は正確?」の穴埋め問題