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

unity study

Unityでサクッとモックを作れるようになることを目指して、基本的なテクニックを抑えていく過程を残すブログのつもりだったけど、今はただ自分のトラブルシューティングメモになってるブログ

SendMessageの謎挙動

PhotonUnityNetworkingを使っていて、OnPhotonJoinRoomFailed(object[] log) が呼ばれず、OnPhotonJoinRoomFailed()が呼ばれるという現象に遭遇し、色々と調査していたらどうもSendMessageの不思議な挙動が原因のようだ。
ちなみにUnity5.3.5f1での確認。
追記:Unity5.4.0f3でも検証したが同じ挙動

using UnityEngine;

public class SendMessageTest : MonoBehaviour
{
	void Foo()
	{
		Debug.Log("Foo() 1");
	}
	void Foo(string param)
	{
		Debug.Log("Foo() 2, " + param);
	}

	void Start()
	{
		// 当然こちらは Foo() が呼ばれる
		SendMessage("Foo", SendMessageOptions.DontRequireReceiver);
		// しかしこちらも Foo() が呼ばれる??
		SendMessage("Foo", "test", SendMessageOptions.DontRequireReceiver);
	}
}

何故か、引数付きのSendMessageも引数なしメソッドの方が呼ばれる。
SendMessageってこういう制約あるんだっけか?
で色々試してみたら

using UnityEngine;

public class Test : MonoBehaviour
{
	void Foo(string param)
	{
		Debug.Log("Foo() 2, " + param);
	}
	void Foo()
	{
		Debug.Log("Foo() 1");
	}

	void Start()
	{
		// エラーになる
		// Failed to call function Foo of class SendMessageTest
		// Calling function Foo with no parameters but the function requires 1.
		SendMessage("Foo", SendMessageOptions.DontRequireReceiver);
		// こちらは意図した通り Foo(string) が呼ばれる
		SendMessage("Foo", "test", SendMessageOptions.DontRequireReceiver);
	}
}

えー、メソッドの定義順を入れ替えると挙動が変わる!?
自分ではSendMessage()なんか全く使わんから、今までこういう挙動があること知らんかった。
というか、過去のバージョンではこういう挙動じゃなかったんじゃないかって気もする。
う〜ん、Unityのバージョン変えながら検証するの、めんどいなぁ。