kazumalab tech log

流行りとリラックマと嵐が大好きです。技術的ログ。

UnityでCallbackを行う Part2

かずまです。


久しぶりに更新します。
ちなみに11月ですね!

なんと11/28は僕の誕生日です!
よっ!!ぱちぱち〜。


なので、Amazonのほしいものリストを公開しました!

amzn.asia

就活も終わったり、卒業論文との格闘始まったり、するので物産を恵んでいただけるとめっちゃ嬉しいです!
本もほしい!特にEffective C#!

さてさて、本題へ。

UnityでCallback

これは前回の記事を見ていただくといいかと思います。
blog.kazumalab.com

ラムダ式を使う場合などは
kan-kikuchi.hatenablog.com
こことか参考になります。

基本的に何かの処理が終わったあとに実行したいメソッドを渡しておくと実行される!みたいな便利なものです。
SendMesageよりもこっちがいいかな、って個人的には思ってます。


今回、コードを書いててふと思ったことをメモ、検証しておきます。

流れ

  1. スーパークラスでメソッドFunc()をvirtualで定義
  2. サブクラスでオーバーライド
  3. スーパークラスのAwake()でCallbackにFunc()をセット

疑問

スーパークラスのAwakeはそもそも呼ばれる?

呼ばれた場合privateだからスーパークラスのFunc()が呼ばれる?

検証コード

スーパークラス

namespace CallbackTest {
	public class SuperManager : MonoBehaviour {

		public TestController TController;

		void Awake () {
			TController.SetCallback (Func);
		}

		public virtual void Func () {
			print ("From Super Class");
		}
	}
}

サブクラス

namespace CallbackTest {
	public class SubManager : SuperManager {
		public override void Func ()
		{
			print ("From Sub Class");
		}
	}
}

呼び出すコントローラー

public class TestController : MonoBehaviour {

	public delegate void Callback();
	private Callback callback;

	private void Update () {
		if (Input.GetMouseButton(0)) {
			this.callback();
		}
	}

	public void SetCallback (Callback c) {
		this.callback = c;
	}
}

気持ち

やっぱりCallbackを使うとオブジェクト同士が分離して書くことができるのでいいですね。

結果

Awakeが呼ばれるか?

呼ばれてました!

どっちが呼ばれるの?

f:id:kazumalab:20161123114008p:plain

サブクラスでオーバーライドしたものが呼ばれてます。

また疑問

  • スーパークラスにもAwake書いて、サブクラスにもAwake書いたらどっちも呼ばれる?

検証コード

// Super Class Awake Method.
void Awake () {
	print ("Awake From Super Class");
	TController.SetCallback (Func);
}
// Sub Class Awake Method.
void Awake () {
	print ("Awake From Sub Class");
	TController.SetCallback (Func);
}

中身は同じですが、printでどっちから呼ばれたかを確認します。

結果

f:id:kazumalab:20161123115029p:plain
Subクラスから呼ばれた!

ってことは間違えてスーパークラスのAwakeにセットするコード書いてて、
サブクラスでは全く違うコード書いてたらdelegateには何も登録されてないことになっちゃう?

試しにサブクラスのSetCallbackをコメントアウトしてみます。

!!!

f:id:kazumalab:20161123115427p:plain

ちゃんとNullが返ってくる!
忘れちゃってAwakeに違う処理書いちゃうのはバグの元ですね。

まとめ

どうせ、同じCallback先だし、関数もオーバーライドした側が呼ばれるならスーパークラスに書いちゃった方が手間省ける!って思って今回書いてみました。

結果はスーパークラスではAwakeは使わず、サブクラスで毎回セットする方がいい。

どっちも呼びたい!みたいなときは

answers.unity3d.com

こことかをみるといいですね!