Unityで他のスクリプトのメソッドを呼び出す3つの方法【ゲーム開発】

Unityで他のスクリプトのメソッドを呼び出す3つの方法【ゲーム開発】

ゲームを作っていて、他のスクリプトのメソッドを使いたいケースは多々あります。Unityでシーン内のGameObjectにアタッチしたスクリプトを使う方法は主に以下の3つ方法があります。

  1. SendMessageを使う
  2. EventSystemsを使う
  3. GetComponentする

それぞれの方法についてメリット、デメリットを挙げ、使い分けができるように共有できればと思います。

 

 

SendMessageを使う

GameObject.SendMessage()を使って対象のゲームオブジェクトにあるメソッドを実行します。

 

メソッド名をstringで指定し、対象のオブジェクトにアタッチされたスクリプトで同じ名前のメソッドがあれば起動します。

例えば、メッセージを送信するゲームオブジェクトから、対象のゲームオブジェクトのメソッドを呼び出してみます。以下のスクリプトを別々のオブジェクトにアタッチしてゲームを実行すると、『SendMessageCaller』が『SendMessageTarget』の『ShowLog()』のスクリプトを呼び出してコンソールにメッセージが出力されます。

SendMessageCallerのスクリプト

 

SendMessageTargetのスクリプト

 

SendMessageのメリット

スクリプトのサンプルを見てもらうと分かる通り、呼び出し方が簡単なので実装しやすいです。

SendMessageのメソッドはGameObjectクラスに含まれているので、特別な準備なども必要ないのがいいですね。初心者向けのチュートリアルだとこの方法で別のスクリプトのメソッドを呼び出していることが多いように思います。

 

SendMessageのデメリット

文字列でメソッドを指定することから、対象のメソッド名が変わるとIDEでは検知できず、自力で気付く必要があります。

また、引数を1つしか指定できないのが痛いところ。しかし引数のためにstructなどを作っておけばいくつか渡せます。

 

SendMessageの総評

最近だとSendMessageを使っているという話はあまり聞かないような……?

Unityのマニュアルでも『EventSystemsはSendMessageを置き換えるために設計された』とあるので、次に紹介するEventSystemsを使用するのが主流だと思います。

 

EventSystemsを使う

メッセージシステムを使ってメソッドを呼び出します。

 

このメッセージシステムはuGUIで使われている方式で、例えばButtonコンポーネントなどでクリックやタップを検知してメソッドを呼びますが、あれもイベントシステムです。

こちらの方法ではインタフェースを使ってメソッドを実装するようにしています。

SendMessageの場合と同様に、メッセージを送信するゲームオブジェクトから、対象のゲームオブジェクトのメソッドを呼び出してみます。以下のスクリプトを別々のオブジェクトにアタッチしてゲームを実行すると、『EventSystemsCaller』が『EventSystemsTarget』の『EventCall()』のスクリプトを呼び出してコンソールにメッセージが出力されます。

また、インタフェースのスクリプトについては特定のオブジェクトにアタッチする必要はありません。

EventSystemsCallerのスクリプト

このスクリプトでは『NotifyEvent』のメソッドの中でExecuteEvents.Execute()を呼び出しています。(メソッド名はNotifyEventでなくても任意でつけて大丈夫です)

個人的にこの引数のラベルと引数の変数を対応する書き方が分かりやすかったのでこのような書き方にしています。functorは対象のインタフェースのどのメソッドを呼ぶかの指定で、上のように別のメソッドを作って呼んでもいいですし、ラムダ式で指定してもOKです。こちらも個人的に別のメソッドを作っておく方がやりやすかったのでこうしています。

 

EventSystemsTargetのスクリプト

メソッドを呼び出される側のスクリプトではインタフェースを実装し、対象のメソッドをpublicで作っておきます。こちら側はシンプルに実装できますね。

 

IEventCallerのスクリプト

インタフェースのスクリプトでは、classとして宣言するのではなくinterfaceとして宣言します。また、IEventSystemHandlerを継承します。usingで『UnityEngine.EventSystems』を宣言しておくことも忘れずに。

 

EventSystemsのメリット

SendMessageと比べると処理が早いのと、インタフェースを使ってメソッドの実装を強制するのでIDEでメソッド名の変更を追いやすいです。

引数の数も柔軟に対応できるのがグッド。

 

EventSystemsのデメリット

初心者だと書き方に迷うかもしれません。今だから言いますが、最初は何しているのか全く分かりませんでした(笑)

サンプルを見ながらひとつひとつ分解して確認していくことで理解できるようになります。

インタフェースのスクリプトを作成するのも初心者の立場からするとちょっと大変かも? とも思います。

 

EventSystemsの総評

慣れるまでは書き方に迷ったので、サンプルコードを見ながら真似して実装してみることをおすすめします。

ただプログラムとして見ると変更に強いというのは大きなメリットですし、パフォーマンス面でも優れているので個人的にはぜひこの方法をマスターして欲しいと思っています。

 

GetComponentする

コンポーネントを操作するときに使うGetComponentを使ってスクリプトを操作できるようにします。

 

これは一番簡単で分かりやすい方法です。

こちらもSendMessageやEventSystemsの場合と同様に、メッセージを送信するゲームオブジェクトから、対象のゲームオブジェクトのメソッドを呼び出してみます。以下のスクリプトを別々のオブジェクトにアタッチしてゲームを実行すると、『GetComponentCaller』が『GetComponentTarget』の『ShowLog()』のスクリプトを呼び出してコンソールにメッセージが出力されます。

 

GetComponentCallerのスクリプト

シンプルにGetComponentしてそのままメソッドを実行しています。publicなメソッドならこのように呼ぶことができます。

実際に使う場合はGetComponentの処理を何度も呼ばなくて済むようにフィールドに参照を保持(キャッシュ)しておくと良いでしょう。

 

GetComponentTargetのスクリプト

publicなメソッドとして用意しておくことで、他のスクリプトから呼び出すことができます。

 

GetComponentのメリット

スクリプトもGetComponentできるので、publicなメソッドを呼び出すことができます。普段コンポーネントを操作している時と同じような感覚で使えることから分かりやすいのがポイントです。

 

GetComponentのデメリット

publicにしているフィールドに値をセットすることもできるので注意が必要です。インスペクターウィンドウからオブジェクトなどをセットするためにpublicにすることがありますが、これを別のスクリプトからもできてしまう点は注意が必要です。

必要なのは1つのメソッドなのに、複数のフィールドやメソッドが公開されているのはオブジェクト指向の考え方からもよろしくありません。

使うなら自分ひとりで作っているゲームが良いかも。

また、シーン内に1つしかないオブジェクトにアタッチされたスクリプトをGetComponentするのはそこまで重くないですが、例えばシーンに10体いる敵キャラのコントローラースクリプトをGetComponentして操作します、だとちょっと重いですし、スクリプトも複雑になるかもしれません。この場合はEventSystemsを使った方がシンプルになることもあります。

 

GetComponentの総評

シンプルで分かりやすいのが好みです。

GetComponentはちょっと重い処理なので、もしやるならStart()のタイミングで参照をキャッシュしておくと吉。

 

使い分けの方針

個人的にはSendMessageは使ってなくて、ほぼEventSystemsを使って実装しています。

自分だけで作ってるゲームだったら、シーン内に1つしかないオブジェクトが対象ならGetComponentを使うこともあります。

その場合は必要なメソッドだけpublicにして、インスペクターウィンドウから値を変えたいフィールドはなるべく[SerializeField]にして隠蔽しています。

3日後の自分がアクセスしちゃうかもしれないですからね(笑)

3通りの方法で実装してみて、それぞれメリット・デメリットを踏まえた上で使い分けられるようになると良いでしょう。

 

     

ゲーム開発の攻略チャートを作りました!

CTA-IMAGE

「ゲームを作ってみたいけど、何から手を付けていいか分からない!」


そんなお悩みをお持ちの方向けに、todoがアプリをリリースした経験を中心に、ゲーム作りの手順や考慮すべき点をまとめたe-bookを作成しました。ゲーム作りはそれ自体がゲームのように楽しいプロセスなので、「攻略チャート」と名付けています。


ゲームを作り始めた時にぶつかる壁である「何をしたら良いのか分からない」という悩みを吹き飛ばしましょう!