UnityのSendMessage使ったことないので、記事にしてみました。
SendMessageって?
同じゲームオブジェクト内 にある MonoBehaviour 継承クラス の関数を、文字列で指定して呼ぶことができる MonoBehaviour クラスの関数です。
基本形は、以下のように第1引数にメソッド名、第2引数に引数、第3引数にオプション。オプションは、呼ぶ対象の関数が存在しない場合にエラーとするか(RequireReceiver)、しないか(DontRequireReceiver)です。デフォルトのオプションは RequireReceiver です。
1 2 3 4 5 6 7 8 9 10 11 |
public class Parent : MonoBehaviour { void Start () { SendMessage("Echo", "Hello World", SendMessageOptions.DontRequireReceiver); } public void Echo(string message) { print(message); } } |
とりあえずメンバ関数のEchoを読んでみる。直接呼べばええやんとか言ってはいけない。
ちゃんと指定した関数が呼ばれた。
一応、SendMessageは、同じゲームオブジェクト内なら別のスクリプトも呼べるので試してみます。
1 2 3 4 5 6 7 |
// Parent.cs public class Parent : MonoBehaviour { void Start () { SendMessage("Echo", "Hello World", SendMessageOptions.DontRequireReceiver); } } |
1 2 3 4 5 6 7 8 |
// Parent2.cs public class Parent2 : MonoBehaviour { public void Echo(string message) { print("Parent2の" + message); } } |
呼ばれました。
これ、複数のスクリプトに同じメソッドがあるとどうなるんでしょう。
どっちも呼ばれるらしい。
同じメソッドを持つスクリプト群をまとめて呼び出す場合に使えってことでしょうか?
気をつけたい点
関数名を文字列で渡すためタイポしても、コンパイルエラーにはならないです。
そのため、タイポに気づかず実行時にバグが見つかるケースも起きうるかと思います。
あとどこから呼ばれているのか辿るのがつらそう。色々と使いづらさが目立ちますね…
類似関数
SendMessageは、同じゲームオブジェクト内が対象でしたが、親ゲームオブジェクトに対象を広げたSendMessageUpwardsと子ゲームオブジェクトに対象を広げたBroadcastMessageがあります。