便利らしいdelegateについて【Unity】

  • URLをコピーしました!

イベント処理やコールバックが簡単になるらしいdelegate。わかる単語が一つもないのでdelegateから順々に調べていきたいと思います。

目次

delegateとは

delegateは、メソッドへの参照を表す型です。

delegateの最大の特徴は、メソッドを引数として扱ったり、複数のメソッドを一度に呼び出したりできます。

使い方

定義から具体的な例まで書いていきます。

定義の仕方

delegateを使うにはまず以下の形で宣言します。

delegate 引数の型 delegate型名 戻り値の型

例えば、delegate void MyDelegate(int value);は、int型の引数をとり、戻り値がないメソッドを参照できるdelegateです。

インスタンス化する

次に既存のメソッドを指定してインスタンス化します。

void MyMethod(int value)
{
    // メソッドの処理
}

MyDelegate myDelegate = new MyDelegate(MyMethod);

呼び出す

最後に呼び出します。

myDelegate(10);

ここまでのまとめ

今までのをまとめるとこうなります。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class DelegateExample : MonoBehaviour
{ 
    delegate void MyDelegate(int value); //delegateの定義
    void MyMethod(int value)
    {
        Debug.Log(value);// メソッドの処理
    }
    void Start()
    {
        MyDelegate myDelegate = new MyDelegate(MyMethod); //インスタンス化
        myDelegate(10); //呼び出し
    }
}

適当なオブジェクトにスクリプトをアタッチしたらちゃんとログが出ます。

10
UnityEngine.Debug:Log (object)

ここまでやってみて

さて、ここまでやってみて基本的なことは分かりました。しかし一つ思うことがあります。

delegate挟まなくても指定したメソッドを直接呼び出せばばよくね?

確かにここまで別にdelegateを使う意味は全くないように感じます。

ですがここからdelegateを使うメリットを紹介します。

delegateを使う利点

複数のメソッド呼び出しが簡単にできる

以下に複数のメソッドを扱うスクリプトを載せます。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;


public class DelegateExample : MonoBehaviour
{
    delegate void MyDelegate(string message); //Delegateの定義
    private void Start()
    {
        // Delegateのインスタンス化
        MyDelegate myDelegate = new MyDelegate(PrintMessage);

        // Delegateの呼び出し
        myDelegate("Hello, World!");

        // Delegateにメソッドを追加
        myDelegate += ShowMessage;

        // Delegateの呼び出し(複数のメソッドが呼び出される)
        myDelegate("Welcome!");

        // Delegateからメソッドを削除
        myDelegate -= ShowMessage;

        // Delegateの呼び出し(削除されたメソッドは呼び出されない)
        myDelegate("Goodbye!");
    }

    private void PrintMessage(string message)
    {
        Debug.Log("Print: " + message);
    }

    private void ShowMessage(string message)
    {
        Debug.Log("Show: " + message);
    }
}

DelegateExampleクラスにMyDelegateを宣言し、それを使用して2つのメソッドを呼び出しています。Startメソッド内で、myDelegateにメソッドを追加したり削除を行っています。

以下が実行したときのログです。

Print: Hello, World!
Print: Welcome!
Show: Welcome!
Print: Goodbye!

複数のメソッドを簡単に呼び出したり、削除したりできるのはdeligateを使う大きな利点です。

FunctionとActionを使った定義の省略

今までdeligateを使うときは

delegate 引数の型 delegate型名 戻り値の型

で定義していましたが、ActionとFunctionを使うことで省略することができます。

ActionとFunctionは関数を参照する型です。

Actionを使って定義を省略してみます。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class DelegateExample : MonoBehaviour
{ 
    delegate void MyDelegate(int value); //delegateの定義
    void MyMethod(int value)
    {
        Debug.Log(value);// メソッドの処理
    }

    void Start()
    {
        MyDelegate myDelegate = new MyDelegate(MyMethod); //インスタンス化
        myDelegate(10); //呼び出し
    }
}

Actionなし

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System; //Actionを使うために追加

public class DelegateExample : MonoBehaviour
{
    //定義の削除
    void MyMethod(int value)
    {
        Debug.Log(value); // メソッドの処理
    }

    void Start()
    {
        // Actionデリゲートのインスタンス化
        // 引数としてint型の値を受け取り、戻り値はなし
        Action<int> myDelegate = new Action<int>(MyMethod); 
        myDelegate(10); // 呼び出し
    }
}

Actionあり

Actionは戻り値なし、Functionは戻り値ありです。

今回は元が戻り値なしだったので、Actionで実行しました。

//引数がstring
Action<string> action1;
//引数がstringとint
Action<string, int> action2;

//返り値がint
Func<int> func1;
//引数がstring、返り値がint
Func<string, int> func2;

参考

(:3[kanのメモ帳]
デリゲート(Delegate)やイベント(Event)とは【C#】 - (:3[kanのメモ帳] はじめに DelegateとEventって何が違うの?だとか、ラムダ式ってどうやって記述するの?という状態なので、今回は勉強がてら、デリゲートについてまとめてみた記事です。
よかったらシェアしてね!
  • URLをコピーしました!
目次