【Unity】Buttonクリック時に呼び出すスクリプトを共通化する方法

どんなにシンプルなゲームでもButtonの1つや2つはあると思います。
しかし、ひとつのButtonに対して1スクリプトを作成した場合、シーンにButtonが10個あったらスクリプトも10個作成しなくてはなりません。
こういったモジュールがProjectウィンドウを埋め尽くす事態は管理上良くありません。

では、1スクリプト内で関数を分けるように実装すると・・・
    public void OnClick1()
{
Debug.Log("Button1が押された");
    }

    public void OnClick2()
    {
        Debug.Log("Button2が押された");
    }
という具合に一見まとまるのですが、
結局、Button Compornet の On Click() で作成した関数を一つ一つ指定しなければなりません。
途中で気づかずに OnClick7() を2回指定してしまったりして不具合の元になりやすいです。

作るスクリプトは最小限に、選択する関数も全部同じ!が理想です。

①継承元となる親クラス

using System.Collections;
using UnityEngine;

public class BaseButtonController : MonoBehaviour
{
public BaseButtonController button;

public void OnClick()
{
if (button == null) throw new System.Exception("Button instance is null!!");
button.OnClick(this.gameObject.name);
}

protected virtual void OnClick(string objectName)
{
Debug.Log("Base Button"); // 通常呼ばれない
}
}
BaseButtonController.cs というスクリプトを作成します。


②親クラスを継承した子クラス

using System.Collections;
using UnityEngine;

public class SampleButtonController : BaseButtonController
{
protected override void OnClick(string objectName)
{
// オブジェクトの数だけ処理を分岐
if ("Button1".Equals(objectName)) this.Button1Click();
else if ("Button2".Equals(objectName)) this.Button2Click();
else throw new System.Exception("Not implemented!!");
}

private void Button1Click()
{
Debug.Log("Button1 Click");
}

private void Button2Click()
{
Debug.Log("Button2 Click");
}
}

今回は、SampleButtonController.cs という名前にしました。
タイトルシーンで使うなら TitleButtonController.cs にするなど、画面単位で管理しましょう。

このスクリプトのポイントは黄色マーキーの部分です。
デフォルトでは MonoBehaviour を継承した状態になっていますが、それを先ほど作成した親クラス BaseButtonController に変更しています。


③アタッチとアウトレット接続

a) ヒエラルキー上に空のGameObjectを作成し、名称を SampleButtonController に変更。
  そこに、子クラスのスクリプト SampleButtonController.cs をアタッチ。 
  publicフィールド Button は None のままでOKです。

b) Buttonオブジェクトには親クラスのスクリプト BaseButtonController.cs をアタッチ。
  publicフィールド Button に、ヒエラルキー上の SampleButtonController をアウトレット接続。

c) ButtonオブジェクトのButton Compornet > On Click() に、Buttonオブジェクトを接続。
  BaseButtonController > OnClick() 関数を選択。
  これを全てのボタンに対して行います。

これで完了です。

実行するとこうなります。

ボタン共通化1.PNG

ボタンを押すと・・・

ボタン共通化2.PNG

このように出力されました。

規模の小さなゲームだとつい力技でスクリプトを量産してしまうのですが、こういったオブジェクト指向のクラス継承を使うと後の拡張がしやすくなります。