読者です 読者をやめる 読者になる 読者になる

テラシュールブログ

旧テラシュールウェアブログUnity記事。主にUnityのTipsやAR・VR、ニコニコ動画についてのメモを残します。

SendMessageに変わる新しいメッセージシステム、ExecuteEvents.Execute

Unity スクリプト

Unity 4.6よりSendMessageに変わる新しいメッセージングが登場してしまいました。その名もExecuteEvents.Executeです。詳しくは下のマニュアルに書いてあります。

Unity - マニュアル: メッセージシステム

 

この機能は、特定のインターフェースを持つコンポーネントを一括で操作する機能を有しています。要するに文字列ではなくインターフェースでメソッドを呼び出すSendMessageみたいなものです。

目次

ExecuteEvents.Executeの使い方について

サンプル

例えば、以下の様なインターフェースがあるとします。また、それを継承したコンポーネントも用意します。

gist.github.com

後は、この継承したオブジェクトを呼び出します。

gist.github.com

これで、ターゲットに指定したオブジェクトのコンポーネント(上記のコードは自分と同じGameObjectにアタッチされているコンポーネント)に対して、何らかの処理を加える事が出来ました。

f:id:tsubaki_t1:20150413001506p:plain

ExecuteEvents.Executeの概要

ポイントはExecuteの型指定にInterfaceであるIRecieveMessageを指定している所と、受信側に設定するインターフェースがIEventSystemHandlerを継承している所です。

これで、Executeはどのメソッドを呼び出すかを把握し、適当なメソッドを呼び出すことが出来ます。

この呼び出しは特定のコンポーネントではなく該当のインターフェースを継承している指定オブジェクトの全てのコンポーネントに適応されます。例えば下の画像のように、インターフェースを継承しさえすれば、一括でメソッドが呼び出せます。

f:id:tsubaki_t1:20150413002603p:plain

また、送信元はスクリプトデバッグ&CallStackで見つけることも出来ます。これは実際に動いている状態で誰が送信したかを把握出来るので、それなりに便利です。

tsubakit1.hateblo.jp

f:id:tsubaki_t1:20150413025905p:plain

継承されてるか判断する

なお該当のインターフェースをオブジェクトが持つコンポーネントが継承しているかは、以下のメソッドで確認することが出来ます。

ExecuteEvents.CanHandleEvent<T>(gameObject);

ExecuteEvents.Executeは受信側がインターフェースを継承したコンポーネントを持っていなくてもエラーを出力しないので、受信先がない場合はエラーとしたい場合、CanHandleEventで事前にチェックすると良さそうです。

SendMessageとの違い

ExecuteEvents.ExecuteのSendMessageとの違いは5つ。

送信側・受信側が見つけやすい

一つはメソッドの送信側・受信側を見つけることが容易になる事です。

このExecuteEvents.Executeのルールは「特定のインターフェース経由で呼ぶこと・特定のインターフェースを継承すること」です。つまりお互いインターフェースに関連するため、インターフェースで検索すれば簡単に送信もしくは受信コンポーネント一覧を入手できます。

またインターフェースを強制する事でメソッドの用途や呼ばれるタイミングが文字列呼び出しのSendMessageより分かりやすくなります。

f:id:tsubaki_t1:20150413003055p:plain

コールバック一覧をエディタで確認できる

2つ目は、UnityのInspectorから受信側のコールバック一覧が表示できる事です。IEventSystemHandlerを継承しているインターフェースを持つコンポーネントは、Inspectorに新しくInetrceptedEventsの項目が表示されます。この項目にはどのコンポーネントが、どのメソッドを受信する(可能性がある)事を示してくれます。

f:id:tsubaki_t1:20150413003417p:plain

リファクタリングが容易

3つ目はリファクタリングの容易さです。

メソッド名を変更したければ、インターフェースを変更すればOKです。インターフェース名の変更は、IDEMonodevelop等)の力でリネームしてしまいます。手書き変更ダメ絶対。

f:id:tsubaki_t1:20150413003630p:plain

引数の指定が容易

4つ目は、引数を好きなだけ追加できる事です。

インターフェース経由で呼んでいるだけなので、引数を増やしたり減らしたり、あまつさえCallbackを渡したりする事も出来ます。さらに、型が指定出来るので呼び出し元・呼び出し先も安心です。

高速

SendMessageと比較してとても高速らしいです。uGUIラウンドテーブルにて