ActionEventHandlerDelegateUnityEventFunc
について
1. 通常の利用方法
-
Action:
戻り値がなく、引数がない、もしくは1つ以上の引数を取ることができるデリゲートです。 -
EventHandler:
標準的なC#のイベントシステムで、通常、イベント発生元 (sender) とイベントデータ (EventArgs) を渡します。 -
Delegate:
カスタムのデリゲートを定義でき、任意の引数と戻り値を設定可能です。 -
UnityEvent:
Unityの特有のイベントシステムで、インスペクターから設定可能なイベントです。デフォルトでは戻り値がなく、引数はオプションです。 -
Func:
戻り値を持つデリゲートで、1つ以上の引数を取ることができます。
2. 引数を取る場合 (複数の引数を取る場合も含む)
各デリゲートやイベントで、引数を取る場合の例です。
Action
using System;
public Action<string, int> onAction;
void Start()
{
onAction += (message, number) => Debug.Log($"{message} - {number}");
onAction?.Invoke("Message", 42);
}
Action<T1, T2>のように複数の引数を取ることが可能です。
EventHandler
public event EventHandler<CustomEventArgs> onEvent;
public class CustomEventArgs : EventArgs { public string Message; public int Number; }
void Start()
{
onEvent += (sender, e) => Debug.Log($"{e.Message} - {e.Number}");
onEvent?.Invoke(this, new CustomEventArgs { Message = "Event message", Number = 42 });
}
EventArgsをカスタムして複数のデータを渡せます。
Delegate
public delegate void CustomDelegate(string message, int number);
public CustomDelegate onCustomEvent;
void Start()
{
onCustomEvent += (message, number) => Debug.Log($"{message} - {number}");
onCustomEvent?.Invoke("Delegate message", 42);
}
- 任意のシグネチャでカスタムデリゲートを作成できます。
UnityEvent
using UnityEngine.Events;
public UnityEvent<string, int> onUnityEvent;
void Start()
{
onUnityEvent.AddListener((message, number) => Debug.Log($"{message} - {number}"));
onUnityEvent?.Invoke("UnityEvent message", 42);
}
UnityEvent<T1, T2>のように複数の引数を設定できます。インスペクターから引数を設定することも可能です。
Func
public Func<string, int, string> onFunc;
void Start()
{
onFunc += (message, number) => $"{message} - {number}";
string result = onFunc?.Invoke("Func message", 42);
Debug.Log(result);
}
Func<T1, T2, TResult>のように複数の引数を取ることができ、最後の型は戻り値です。
3. 戻り値を取る場合
Action、EventHandler、UnityEventは戻り値を持ちませんが、FuncやカスタムDelegateを使うことで戻り値を持たせることが可能です。
Func (戻り値あり)
public Func<string, int, string> onFunc;
void Start()
{
onFunc += (message, number) => $"{message} - {number}";
string result = onFunc?.Invoke("Func message", 42);
Debug.Log(result); // 出力: Func message - 42
}
Funcは戻り値を持つデリゲートで、最後の型パラメータが戻り値の型になります。
Delegate (戻り値あり)
public delegate int CustomDelegate(string message, int number);
public CustomDelegate onCustomEvent;
void Start()
{
onCustomEvent += (message, number) => message.Length + number;
int result = onCustomEvent?.Invoke("Hello", 5);
Debug.Log(result); // 出力: 10
}
- カスタムデリゲートに戻 り値を持たせることが可能です。
4. 違いや使い所についてのまとめ
| 特徴 | Action | EventHandler | Delegate | UnityEvent | Func |
|---|---|---|---|---|---|
| 戻り値 | なし | なし | 任意 | なし | あり |
| 引数 | 最大16個 | EventArgsを使って渡す | 任意 | UnityEvent<T>形式で設定 | 最大16個 |
| インスペクター対応 | なし | なし | なし | あり | なし |
| 使いどころ | シンプルなイベント処理 | C#の標準的なイベント | カスタム処理や複雑なパターン | Unityエディターでイベント設定したい場合 | 戻り値が必要な場合 |
使い所まとめ:
-
Action:
- シンプルなイベント処理や、戻り値が不要な場合に便利。
- 引数を使った汎用的なイベント処理に向いています。
-
EventHandler:
- 標準的なC#イベント。複数のリスナーやイベント発生元、追加データ (
EventArgs) を伝えたい場合に使用します 。 - 複雑なイベントのやり取りが必要な場面で使いやすいです。
- 標準的なC#イベント。複数のリスナーやイベント発生元、追加データ (
-
Delegate:
- カスタムのデリゲートを定義したい場合。引数や戻り値を自由に定義でき、柔軟なイベント処理を構築できます。
- 特定の処理に合わせたイベントや、シグネチャを細かくカスタマイズしたいときに適しています。
-
UnityEvent:
- Unityのエディターからも設定可能なイベントシステム。インスペクターからイベント設定ができるため、スクリプトに依存せずイベント処理を追加・管理したい場合に最適です。
- UIやゲームオブジェクトのインタラクションに向いています。
-
Func:
- 戻り値が必要なイベントやデリゲートを使いたい場合に適しています。
- 例えば、処理の結果を返したり、データを計算して返す必要がある場合に使います。
サンプルコード
Action、EventHandler、Delegate、UnityEvent、Funcを使ったサンプルコード
1. Action の利用例
using UnityEngine;
using System;
public class ActionExample : MonoBehaviour
{
// 引数付きのAction (stringとintを受け取る)
public Action<string, int> onAction;
void Start()
{
// Actionにメソッドを登録
onAction += PrintMessage;
// Actionを実行
onAction?.Invoke("Hello from Action", 42);
}
void PrintMessage(string message, int number)
{
Debug.Log($"{message} - {number}");
}
}
- この例では、
Action<string, int>を使い、stringとintを引数に取るイベントを作成しています。
2. EventHandler の利用例
using UnityEngine;
using System;
public class EventHandlerExample : MonoBehaviour
{
// カスタムEventArgsクラス
public class CustomEventArgs : EventArgs
{
public string Message { get; set; }
public int Number { get; set; }
}
// EventHandler (CustomEventArgsを使う)
public event EventHandler<CustomEventArgs> onEvent;
void Start()
{
// EventHandlerにメソッドを登録
onEvent += OnEventTriggered;
// イベントを発生させる
onEvent?.Invoke(this, new CustomEventArgs { Message = "Hello from EventHandler", Number = 42 });
}
void OnEventTriggered(object sender, CustomEventArgs e)
{
Debug.Log($"{e.Message} - {e.Number}");
}
}
- この例では、
EventHandlerを使い、カスタムEventArgsを渡してデータをやり取りしています。
3. Delegate の利用例
using UnityEngine;
public class DelegateExample : MonoBehaviour
{
// カスタムデリゲート (stringとintを受け取り、intを返す)
public delegate int CustomDelegate(string message, int number);
// カスタムデリゲートの変数
public CustomDelegate onCustomEvent;
void Start()
{
// デリゲートにメソッドを登録
onCustomEvent += CalculateStringLengthAndAddNumber;
// デリゲートを実行し、結果を取得
int result = onCustomEvent?.Invoke("Hello from Delegate", 42) ?? 0;
Debug.Log($"Result: {result}");
}
// stringの長さとnumberを足して返す
int CalculateStringLengthAndAddNumber(string message, int number)
{
return message.Length + number;
}
}
- この例では、カスタムデリゲートを使い、
stringとintを受け取り、処理結果としてintを返しています。
4. UnityEvent の利用例
using UnityEngine;
using UnityEngine.Events;
public class UnityEventExample : MonoBehaviour
{
// 引数付きのUnityEvent (stringとintを受け取る)
public UnityEvent<string, int> onUnityEvent;
void Start()
{
// UnityEventにリスナーを登録
onUnityEvent.AddListener(PrintMessage);
// UnityEventを実行
onUnityEvent?.Invoke("Hello from UnityEvent", 42);
}
void PrintMessage(string message, int number)
{
Debug.Log($"{message} - {number}");
}
}
- この例では、
UnityEvent<string, int>を使い、引数を渡してイベントを処理しています。インスペクターからもリスナーを設定できます。
5. Func の利用例
using UnityEngine;
using System;
public class FuncExample : MonoBehaviour
{
// 戻り値付きのFuncデリゲート (stringとintを受け取り、stringを返す)
public Func<string, int, string> onFunc;
void Start()
{
// Funcにメソッドを登録
onFunc += FormatMessage;
// Funcを実行し、戻り値を取得
string result = onFunc?.Invoke("Hello from Func", 42);
Debug.Log(result);
}
// stringとintを受け取り、整形されたメッセージを返す
string FormatMessage(string message, int number)
{
return $"{message} - {number}";
}
}
- この例では、
Func<string, int, string>を使い、引数を受け取って整形し、戻り値を返しています。
6. それぞれの使い所のまとめ
| 種類 | 用途 | Unityインスペクターで設定可能 | 戻り値 | 引数 |
|---|---|---|---|---|
| Action | シンプルなイベント処理に最適。戻り値は不要。 | なし | なし | 最大16個 |
| EventHandler | 標準的なイベントシステム。イベント発生元やデータの管理が必要な場合。 | なし | なし | EventArgsで管理 |
| Delegate | 自由な引数・戻り値を設定可能なカスタムイベント。 | なし | あり | 任意 |
| UnityEvent | Unityエディターでイベントを設定したい場合。UIなどのイベント管理に最適。 | あり | なし | 最大4つまで |
| Func | 戻り値が必要な場合に使用。結果を返す処理に向いている。 | なし | あり | 最大16個 |
ファイルを分けて書く
実際の開発では、スクリプトが別ファイルに分かれることが多いです。特に、以下のようなケースではファイルを分けることが推奨されます。
1. クラスやデリゲートの再利用
- カスタムデリゲートやEventArgsを定義した場合、複数のクラスで再利用したいことが多いです。そのため、これらの定義を別のファイルに分けておくと、管理や拡張が容易になります。
2. 機能ごとに分ける
- 例えば、ある機能に特化したイベントを管理するクラスと、他のクラスでイベントを呼び出す側(
Invoker)、または受け取る側(Listener)が異なる場合は、それぞれ別のスクリプトに分けます。これにより、クラスごとの責任を明確にし、コードの保守性を高めることができます。
3. Unityの実践的なプロジェクト構成
- Unityプロジェクトでは、スクリプトを機能ごとに整理することが重要です。通常、次のような構成にすることが多いです。
- イベントデリゲートやカスタムクラスの定義は別ファイルにまとめる。
- メインのゲームロジックやイベントの呼び出しは個別のクラスにする。
- イベントリスナーやイベント発生元のクラスは、別々のスクリプトファイルに分ける。
実際にファイルを分けた例
1. CustomEventArgs.cs
using System;
public class CustomEventArgs : EventArgs
{
public string Message { get; set; }
public int Number { get; set; }
}
- カスタム
EventArgsの定義は別ファイルに分け、複数のスクリプトから利用できるようにします。