UNITYのシーンを ひも解き把握するには…

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