Unityでのイベントの処理
FlashではEventListenerという組み込みの機構があってとても便利に実装できる。Unityではどんな実装が考えられるか試してみた。
例えばステージをクリックすると自身のオブジェクトが回転し、60度以上回転すると自身を破棄するようなものをFlashで実装すると。
package { /** * import. */ import flash.display.MovieClip; import flash.events.MouseEvent; /** * イベントテスト。 */ public class EventTest extends MovieClip { /** * コンストラクタ。 */ public function EventTest():void { // イベント追加 this.stage.addEventListener(MouseEvent.CLICK, this.onClick); } /** * クリッイベント。 */ private function onClick(evt:MouseEvent):void { this.rotation += 10; if (this.rotation >= 60) { this.stage.removeEventListener(evt.type, arguments.callee); this.parent.removeChild(this); } } } }
こんな感じ。
Unityでも作ってみました。
>>サンプル
4つともクリックすると回転し、60度より大きく回転するとGameObjectが破棄され、イベントも消される。同じ動きだけど、4つとも違う実装。
一番左のキューブはコンポーネントを取得して直接メソッドを呼び出すやり方。
登録できる型が決めうちで実装するメソッドをボタンが知っている必要があるので、汎用的なボタンではなくなってしまう。コンポーネント間の依存が強い関係ならいいけど、関係を粗にしておきたいときにはこれではあまりよろしくない。
左から2番目はUnityではよく使われるSendMessage()。
GameObjectにSendMessageを行うと、そのオブジェクトが持っているコンポーネントに対して指定のメソッド名(Stringで渡す)を呼び出すことができる。登録されているコンポーネントすべてに指定の命令が出せるのでGameObjectのイベントで全てのコンポーネントに命令を出すのに便利。またGameObjectを登録するので、インスペクターから追加したいGameObjectをドラッグして追加できるのも便利。
欠点としては引数が1つまでなのとメソッド名をStringで渡すのでミスしててもコンパイルエラーにはならない。呼び出すメソッド名も固定になってしまうので、重複しないように気をつけないといけないなど注意点はいくつかありそう。
3番目はメソッドを追加する方法。これであれば呼び出すメソッドを登録できるのでFlashのEventListenerのように使えて便利。追加や削除なんかはList
4番目はC#の組み込みのeventキーワード、System.EventHandler、System.EventArgsを使った方法。これはEventListenerのような使い方ができて、登録時は+=、削除時は-=など視覚的に使えて便利。
EventHandler使わなくとも、eventキーワードと自身でdelegateを作ってあげてもOK。
ボタン側も
using System; public event EventHandler OnClick;
とだけあればOK。メソッドなどを登録しておく配列などは勝手に用意されているのであとは任意のタイミングでOnClick(this, EventArgs.Empty)と呼び出すだけでOK。
それぞれ使いどころが違うのでケースバイケースで使う感じですが、FlashでいうEventListenerのような使い方は4番目でしょうか。
[…] Unity4.6からuGUIが追加された際に、UnityEventというイベントシステムも追加されました。 uGUIと同時に追加されたので、uGUIで扱うイベントシステム系かと思ってしまいますがあらゆる場面で利用ができます。 以前、イベントについてどのようなやり方がいいか試してみたんですが、その際に作ったものにUnityEventでのやり方を追加してみました。 […]
[…] イベントの処理 | STAC STAR […]