Comments
Description
Transcript
講演ファイルのダウンロード(PDF)
UNITYのシーンを ひも解き把握するには… • ユニティ・テクノロジーズ・ジャパン 山村 達彦 COPYRIGHT 2015 @ UNITY TECHNOLOGIES 私、 フィールドエンジニア COPYRIGHT 2014 2015 @ UNITY TECHNOLOGIES お仕事 • 技術的な相談に乗る • 問題を解決する COPYRIGHT 2015 @ UNITY TECHNOLOGIES 今回のお話 • プロジェクトをサクっと読む方法 COPYRIGHT 2015 @ UNITY TECHNOLOGIES 何故こんなのが必要になったのか • バグレポートの構造解析 • サンプルシーンの解析 COPYRIGHT 2015 @ UNITY TECHNOLOGIES 何故こんなのが必要になったのか • バグレポートの構造解析 • サンプルシーンの解析 • コード書くの面倒 →昔作ったプロジェクトが読めない COPYRIGHT 2015 @ UNITY TECHNOLOGIES 何故こんなのが必要になったのか • バグレポートの構造解析 • サンプルシーンの解析 • コード書くの面倒 →昔作ったプロジェクトが読めない →もっと楽に解析できるようにすれば… COPYRIGHT 2015 @ UNITY TECHNOLOGIES ルールの確認 COPYRIGHT 2014 @ UNITY TECHNOLOGIES UNITYの構造 COPYRIGHT 2014 2015 @ UNITY TECHNOLOGIES UNITYの構造 • プロジェクト →シーン →オブジェクト →コンポーネント • オブジェクトとコンポーネントが 色々と動いてシーンを構成する。 COPYRIGHT 2015 @ UNITY TECHNOLOGIES プロジェクトの構造 • プロジェクトは複数のシーンを持つ事がある。 • シーンは複数のオブジェクトを持つ。 • オブジェクトは複数のコンポーネントを持つ。 • コンポーネントは複数のアセットへの参照を持つ COPYRIGHT 2015 @ UNITY TECHNOLOGIES オブジェクトが動く ルール COPYRIGHT 2014 2015 @ UNITY TECHNOLOGIES オブジェクトが動くルール • ゲームオブジェクトは、コンポーネント(部品)で 動作する。 • コンポーネントはオブジェクトに複数組み込まれる • コンポーネントはC#もしくはJSで記述する。 COPYRIGHT 2015 @ UNITY TECHNOLOGIES コンポーネントの動き • コンポーネントはコールバックで動作する。 • 独自フレームワークで拡張されてるケースもある。 が、始点はコールバックから。 • Start・Update・FixedUpdate・OnColliderEnter… COPYRIGHT 2015 @ UNITY TECHNOLOGIES 動かない条件 • 非アクティブなオブジェクトは動かない • コンポーネントのないオブジェクトは動かない • 参照もコールバックもないオブジェクトは動かない COPYRIGHT 2015 @ UNITY TECHNOLOGIES オブジェクト間の メッセージのルール COPYRIGHT 2014 2015 @ UNITY TECHNOLOGIES オブジェクトへのメッセージ • SendMessage • BroadcastMessage • SendMessageUpward • AnimationEvent • UnityAction • Eventsystem.Execute • Invoke • StartCoroutine COPYRIGHT 2015 @ UNITY TECHNOLOGIES コンポーネントへのメッセージ • 普通にメソッドコール • event • UnityEvent • StartCoroutine COPYRIGHT 2015 @ UNITY TECHNOLOGIES 参照の構築 • GetComponent(s) • GetComponent(s)InChildren/Parent • FindWithType・FindWithTag • public/SerializeFieldでシリアライズしてシーンで設定 • AddComponentでコンポーネントを設定 COPYRIGHT 2015 @ UNITY TECHNOLOGIES オブジェクト生成の ルール COPYRIGHT 2014 2015 @ UNITY TECHNOLOGIES オブジェクトを作る方法 • Instantiate • LoadLevel • LoadLevelAditive • new GameObject COPYRIGHT 2015 @ UNITY TECHNOLOGIES オブジェクトの元を得る • Resourcesから取得 • AssetBundleから取得 • AddComponentを駆使して取得 • Prefabへの直接参照 • 任意のオブジェクト COPYRIGHT 2015 @ UNITY TECHNOLOGIES ルールを元に情報を集める COPYRIGHT 2014 @ UNITY TECHNOLOGIES コンポーネント呼出の 把握 COPYRIGHT 2014 2015 @ UNITY TECHNOLOGIES どのコンポーネントが何時動くのか • シーン内のコンポーネントは何があるのか? • そのコンポーネントはコールバックを持つのか? • オブジェクトはランタイムで増減する COPYRIGHT 2015 @ UNITY TECHNOLOGIES コールバック • OnCollider/OnTrigger系 →判定に使用される • OnMouse…、及びuGUIコールバック →入力に使用される • On⃝⃝⃝(SendMessageかAnimationEvent) COPYRIGHT 2015 @ UNITY TECHNOLOGIES コンポーネントの列挙 • シーン内にあるオブジェクト情報から コンポーネント一覧を取得し、 コンポーネント一覧からコールバック一覧を取得 …するエディタ拡張を書く。 (リフレクションを使う) • 選択中のオブジェクトで絞込を行うとより便利 COPYRIGHT 2015 @ UNITY TECHNOLOGIES COPYRIGHT 2015 @ UNITY TECHNOLOGIES IEVENTSYSTEMHANDL • IEventSystemHandlerを継承したインターフェースを 持つ場合、Inspectorで確認出来る。 COPYRIGHT 2015 @ UNITY TECHNOLOGIES COPYRIGHT 2015 @ UNITY TECHNOLOGIES 文字列のメソッドコール • 任意のメソッド名で呼ばれる。 • AnimationEvent、SendMessage、 uGUIのEventSystem(シリアライズ)が該当 • これもコールバックとして計上しておくと吉 COPYRIGHT 2015 @ UNITY TECHNOLOGIES COPYRIGHT 2015 @ UNITY TECHNOLOGIES オブジェクトの参照関係の 確認 COPYRIGHT 2014 2015 @ UNITY TECHNOLOGIES コンポーネント参照先の確認 • シリアライズされているフィールドで追跡 • privateな物はdebugで確認 • ランタイムで変わる可能性がある • 参照先が行ったり来たりする COPYRIGHT 2015 @ UNITY TECHNOLOGIES COPYRIGHT 2015 @ UNITY TECHNOLOGIES コンポーネント参照元の確認 • 無理。 →オブジェクトを消した時のリスクが不明 →機能を移植したい場合、何を移植すればよいか不明 • 参照情報を元に被参照リストを作る。 COPYRIGHT 2015 @ UNITY TECHNOLOGIES COPYRIGHT 2015 @ UNITY TECHNOLOGIES 参照先の座標の確認 • オブジェクトだけでなく、矢印を貼ると 非常に追跡が容易。 • 但し量が多すぎると混乱を招くので、 ストリップする仕組みは必要。 COPYRIGHT 2015 @ UNITY TECHNOLOGIES COPYRIGHT 2015 @ UNITY TECHNOLOGIES 参照リストからの削除 • オブジェクトの親子関係で構築した参照 • オブジェクト内で自己完結している参照 • 選択中のオブジェクト内での参照 • 参照関係の整理に便利。 COPYRIGHT 2015 @ UNITY TECHNOLOGIES 参照関係のないオブジェクト • 参照関係とは関係ない、自己完結もしくはコンポー ネントが無いオブジェクトを非表示にすると、 Hierarchyがスッキリしてシーン把握が楽になる。 COPYRIGHT 2015 @ UNITY TECHNOLOGIES COPYRIGHT 2015 @ UNITY TECHNOLOGIES コンポーネントの依存関係 COPYRIGHT 2014 2015 @ UNITY TECHNOLOGIES COPYRIGHT 2015 @ UNITY TECHNOLOGIES コンポーネント内コード検索 • シーン内のコンポーネント一覧から、 特定のコードを持つコンポーネントを取得 …するエディタ拡張を書く。 (MonoScriptでMonobehaviourのコード取得) COPYRIGHT 2015 @ UNITY TECHNOLOGIES COPYRIGHT 2015 @ UNITY TECHNOLOGIES グラフ化 • 参照関係をグラフ化 • dotやgmlといったフォーマットを活用 • コード解析…が無ければ正規表現で頑張る COPYRIGHT 2015 @ UNITY TECHNOLOGIES COPYRIGHT 2015 @ UNITY TECHNOLOGIES MODEL • コンポーネント間の参照とは別に、何らかの (コンポーネントではない)クラスがある場合、 ゲーム進行管理はそっちで行われるケースが多い COPYRIGHT 2015 @ UNITY TECHNOLOGIES シーンを紐解いていく COPYRIGHT 2014 @ UNITY TECHNOLOGIES そのコンポーネントは どのような役割があるのか? COPYRIGHT 2014 2015 @ UNITY TECHNOLOGIES マネージャー系オブジェクト • オブジェクト総数が一つで、コンポーネント的な 参照が多い場合、マネージャークラスの確率が高い • マネージャーは大抵シングルトン。 • 役割は様々(データを持つだけのもの、管理するもの等) • どちらかと言えば外部からのメッセージで動くことが多い COPYRIGHT 2015 @ UNITY TECHNOLOGIES COPYRIGHT 2015 @ UNITY TECHNOLOGIES ギミック系オブジェクト • コライダー等で自己完結するオブジェクト • 他のオブジェクトに対する参照は余り無い (Playerに接続しているケースが多い) • トリガーやアクションをマネージャーに通知する タイプも居る。 • ステージを作る系のゲームによく見る。 COPYRIGHT 2015 @ UNITY TECHNOLOGIES COPYRIGHT 2015 @ UNITY TECHNOLOGIES UPDATEで頑張るドン • メインオブジェクト • 多くの参照を集めているタイプで多い。 • この手のオブジェクトはコードベースで動くため、 コードを読んで処理を追跡する。 • Updateやコルーチンで自発的に動く。 COPYRIGHT 2015 @ UNITY TECHNOLOGIES そのオブジェクトは どうやって参照されたのか COPYRIGHT 2014 2015 @ UNITY TECHNOLOGIES 参照先の状態を見る • 「誰を見る」ではなく「どうやって見つかる」なの で、見られているオブジェクトの持つパラメータに 注目する。 • コードを追うより、実際に参照させて それを見たほうが正直楽だった。 COPYRIGHT 2015 @ UNITY TECHNOLOGIES COPYRIGHT 2015 @ UNITY TECHNOLOGIES ゲーム起動前の参照関係 ゲーム起動後の参照関係 COPYRIGHT 2015 @ UNITY TECHNOLOGIES 参照関係を把握する • 自分で動くか管理されるかの2択 • 被参照が一つの場合、管理されている可能性がある。 大体マネージャー。 • 被参照が多い場合、自分で動く可能性が高い。 大体ギミック。 COPYRIGHT 2015 @ UNITY TECHNOLOGIES 検索パターン • ユニークなタグ(例えばPlayer)を保つ場合、 FindWithTagで検索される • 親子関係の場合、親子関係で検索される。 • 名前で検索される場合もある。 COPYRIGHT 2015 @ UNITY TECHNOLOGIES 対マネージャー(シングルトン) • コンポーネントがマネージャーに自身を 登録する方法と、マネージャーがコンポーネントを 探す方法の2種類がある。 COPYRIGHT 2015 @ UNITY TECHNOLOGIES 何故参照を持つのか • 検索のキャッシュ • 対象の位置を得る為 • 対象のコンポーネントの情報を得る為 • メッセージングの為 COPYRIGHT 2015 @ UNITY TECHNOLOGIES COPYRIGHT 2015 @ UNITY TECHNOLOGIES COPYRIGHT 2015 @ UNITY TECHNOLOGIES そのオブジェクトは 何処から持ってきたのか? COPYRIGHT 2014 2015 @ UNITY TECHNOLOGIES 生成コードの検索 • シーン内に最初から配置されているか? • シーン内でオブジェクトを生成するコードを検索 • ResourcesやAssetBundle等の処理は ラッピングされて独自に管理機能を持つケースが多い。 →その場合はラッパークラスを探す。 COPYRIGHT 2015 @ UNITY TECHNOLOGIES COPYRIGHT 2015 @ UNITY TECHNOLOGIES 該当のプレハブを持つシーンを探す • LoadLevelAditiveの場合、ロードするシーンを探す。 • 生成物がプレハブの場合、事前にシーン内の参照情 報を保持しておくことで、サクっと探せる。 • Reference Viewer(Unite 2014)が便利 https://github.com/anchan828/unitejapan2014/tree/master/ReferenceViewer • 後はシーンをロードするコードを探す COPYRIGHT 2015 @ UNITY TECHNOLOGIES COPYRIGHT 2015 @ UNITY TECHNOLOGIES シーン(YAML)をGREP検索 • メタデータ(シーン・プレハブ)はSerializedObject YAMLへ 変換出来る事を利用する。 • LoadLevelAditiveでプレハブではない場合、 かつオブジェクト名しか分からない場合。 • シーンのフォーマットをYAMLに変換し、Grep検索。 →オブジェクト名は見つかる。 • 後はシーンを読み込むコードを探す COPYRIGHT 2015 @ UNITY TECHNOLOGIES ※追記 • Unity5よりUnityYAMLMergeが導入され、 シーンやプレハブのマージが可能になった。 http://docs.unity3d.com/Manual/SmartMerge.html COPYRIGHT 2015 @ UNITY TECHNOLOGIES このシーンは、 どんな構造なのか COPYRIGHT 2014 2015 @ UNITY TECHNOLOGIES • (実行時に)シーンが持つコンポーネントを知る • オブジェクトの役割と参照関係を知る • オブジェクトが作られる条件を知る • コンポーネントの動くタイミングを知る • コンポーネントの接続方法を知る • オブジェクトの動きを把握すると 大体シーンの構造が判る COPYRIGHT 2015 @ UNITY TECHNOLOGIES 今日紹介したアプローチを簡単に行うエディタ拡張は 近日公開(予定) COPYRIGHT 2014 @ UNITY TECHNOLOGIES FAQ COPYRIGHT 2014 @ UNITY TECHNOLOGIES