スポンサーリンク
UnityUnityメモ

【Unity C#】カスタムイベントの作り方!EventとActionを使いこなそう

Unity

1. はじめに

Unityでゲームを作っていると、「別のスクリプトから特定の処理を呼び出したい」と思う場面がよくありますよね。
例えば「ボタンを押したらキャラクターを動かす」「敵に当たったらHPを減らす」といった処理は、複数のスクリプト同士がやり取りする必要があります。そんなときに役立つのがイベント処理です。

C#には delegate(デリゲート)、ActionFunc といった便利な仕組みがあり、さらにUnityでは UnityEvent を使うことで、インスペクタから直感的に処理を設定できるようになります。これらを正しく理解して使い分けることで、コードの見通しが良くなり、再利用性の高いプロジェクトが作れます。

この記事では、C#の基本的なdelegateからUnity独自のUnityEventまでを、初心者の方にもわかりやすく解説していきます。後半では、実際に「クリックで画像の色を変える」というシンプルなサンプルを作りながら、UnityEventの実践的な使い方を紹介します。

もし「イベント周りの仕組みを一からしっかり理解したい!」という方は、こちらの書籍もおすすめです。C#やUnityの基礎から実践的なコードパターンまで体系的に学べます。


2. C#におけるデリゲートとイベントの基礎

2-1. delegate(デリゲート)とは?

まず最初に知っておきたいのが delegate(デリゲート)です。
簡単にいうと「関数を変数のように扱える仕組み」で、処理をまとめて呼び出したいときにとても便利です。

例えばこんなコードを書いてみましょう。


public delegate void MyDelegate();

public class DelegateSample {
    public MyDelegate onExecute;

    public void Start() {
        onExecute += Hello;
        onExecute?.Invoke();
    }

    void Hello() {
        Debug.Log("こんにちは!デリゲートが呼ばれました。");
    }
}

この例では、onExecuteHello メソッドを登録し、Invoke() で呼び出しています。
?.Invoke()」を使うことで、登録がない場合にエラーを避けられるのもポイントです。


2-2. ActionとFunc

C#には、あらかじめ用意されたデリゲート型である ActionFunc があります。これを使うと、独自にdelegateを宣言しなくてもOKです。

  • Action:戻り値なしの関数をまとめられる
  • Func:戻り値ありの関数をまとめられる

サンプルコードを見てみましょう。


using System;

public class ActionFuncSample {
    public Action onAction;
    public Func<int, int, string> onCalc;

    public void Start() {
        onAction += () => Debug.Log("Actionで処理を実行!");
        onAction?.Invoke();

        onCalc += (a, b) => (a + b).ToString();
        Debug.Log("Funcの結果: " + onCalc?.Invoke(5, 3));
    }
}

この例では、Actionでシンプルなログ出力、Funcで「2つのintを受け取りstringを返す処理」を登録しています。
Action/Funcは一度覚えてしまえば、イベント設計がとてもスッキリしますよ。


2-3. 匿名関数とラムダ式

イベントを登録する際、わざわざ新しいメソッドを作るのが面倒なときは「ラムダ式」を使うと便利です。


// 匿名関数(古い書き方)
onAction += delegate() { Debug.Log("古い書き方"); };

// ラムダ式(推奨される書き方)
onAction += () => Debug.Log("シンプルに書ける!");

ラムダ式は1行なら括弧や波括弧を省略できるので、コードを簡潔に保つことができます。
ただし処理が複雑な場合は、読みやすさを考えて通常のメソッドに分けるのも大切です。


2-4. event修飾子

最後に知っておきたいのが event 修飾子です。
デリゲートをeventとして宣言すると、外部のクラスから勝手に実行されないように制限できます。


public class EventSample {
    public event Action onTriggered;

    public void Trigger() {
        onTriggered?.Invoke();
    }
}

この場合、外部クラスからは +=-= で関数の登録/解除はできますが、直接Invoke()することはできません。
イベントを安全に扱うために、eventは積極的に使っていきましょう。




3. UnityでのActionとUnityEventの活用

3-1. UnityActionとは?

Unityには、C#標準のActionとほぼ同じ働きをする UnityAction という仕組みがあります。
特徴は「返り値がvoid(なし)」である点で、イベントの通知にとてもよく使われます。


using UnityEngine;
using UnityEngine.Events;

public class UnityActionSample : MonoBehaviour {
    UnityAction onEvent;

    void Start() {
        onEvent += SayHello;
        onEvent?.Invoke();
    }

    void SayHello() {
        Debug.Log("UnityActionが実行されました!");
    }
}

using UnityEngine.Events を追加すれば、すぐに利用可能です。Actionと同じように += で追加、-= で解除できます。


3-2. UnityEventの強み

UnityEventは、UnityActionと似ていますが、大きな違いはインスペクタから関数を登録できることです。
スクリプトを書かなくても、UI上で関数を割り当てられるため、非エンジニアの方でも簡単にイベント処理を追加できます。

使い方の流れは以下の通りです:

  1. スクリプトで public UnityEvent onClick; のように宣言
  2. インスペクタに表示される「+」ボタンからオブジェクトを登録
  3. プルダウンで呼び出したい関数を選択

using UnityEngine;
using UnityEngine.Events;

public class UnityEventSample : MonoBehaviour {
    public UnityEvent onClick;

    void Update() {
        if (Input.GetMouseButtonDown(0)) {
            onClick?.Invoke();
        }
    }
}

これで「マウスクリック → Inspectorで登録した処理を実行」という流れが簡単に作れます。
引数1つまでならInspector上で直接値を設定できるのも便利なポイントです。


3-3. インスペクタをもっと便利にする方法

UnityEventは便利ですが、Inspector上で複雑なイベントを管理していると「どこで何が呼ばれているのかわかりにくい…」という問題が出やすいです。
そんなときにおすすめなのが Odin Inspector & Serializer です。Inspectorをカスタマイズできるアセットで、イベントの可視化やデバッグがグッとやりやすくなります。

✅ Odin Inspector & Serializer をアセットストアで見る

このアセットを導入すると、UnityEventやActionを使ったコードの挙動を見やすく管理できるので、学習中の方にもプロジェクト規模が大きい方にもおすすめです。


4. 実践チュートリアル:UnityEventでオブジェクトの色を変える

ここからは、実際に UnityEvent を使ったサンプルを作ってみましょう。
クリックやタップをすると、画像(UIやSprite)の色が変わるシンプルな仕組みを作ります。

4-1. プロジェクト準備

  1. Hierarchy(ヒエラルキー)で右クリック → UI > Image を作成し、白い画像を配置します。
  2. さらに Create Empty を選んで空のオブジェクトを作成し、「Manager」と名前を付けます。

4-2. スクリプトを作成

次に、色を変えるスクリプトを用意します。


// Circle.cs
using UnityEngine;
using UnityEngine.UI;

public class Circle : MonoBehaviour {
    public Color changeColor = Color.red;
    public void ChangeColor() {
        GetComponent&lt;Image&gt;().color = changeColor;
    }
}

このスクリプトを、画像オブジェクトにドラッグ&ドロップでアタッチしてください。Inspectorで色を指定できるようになります。


続いて、クリック検知用のスクリプトです。


// ChangeColorManager.cs
using UnityEngine;
using UnityEngine.Events;

public class ChangeColorManager : MonoBehaviour {
    public UnityEvent onClick;

    void Update() {
        if (Input.GetMouseButtonDown(0)) {
            onClick?.Invoke();
        }
    }
}

このスクリプトは空のオブジェクト「Manager」にアタッチします。


4-3. Inspectorでイベントを登録

  1. 「Manager」を選択し、InspectorのonClickイベントを確認。
  2. +ボタンを押して、新しいイベントを追加。
  3. ヒエラルキーから「画像オブジェクト」をドラッグ&ドロップして登録。
  4. プルダウンから Circle > ChangeColor() を選択。

これで「クリックすると画像の色が変わる」という仕組みが完成です。


4-4. デバッグを効率化する

イベントを複数登録したり、どのタイミングで呼ばれているかを確認したいときはログを出力しますが、Unity標準のコンソールでは情報が埋もれて見づらくなることもあります。
そんなときに便利なのが Editor Console Pro です。

✅ Editor Console Pro をアセットストアで見る

通常のコンソールよりもフィルタリングや検索がしやすく、イベント処理のデバッグがスムーズになります。
UnityEventを多用する開発では特に効果を発揮しますよ。


5. 応用例とベストプラクティス

5-1. ゲーム開発での具体的な活用シーン

イベント処理は、ゲーム内のあらゆる場面で使えます。例えば:

  • UI操作:ボタンを押したらメニューを開く、音量を変更する
  • キャラクター制御:HPがゼロになったら死亡アニメーションを再生
  • アイテム取得:コインを拾ったらスコアを加算
  • ゲーム進行:特定条件を満たしたらイベントシーンに切り替える

このように「何かが起きたら別の処理を呼ぶ」という仕組みは、ほぼすべてのゲームで役立ちます。


5-2. ActionとUnityEventの使い分け

イベントの書き方にはいくつか選択肢があります。次の基準で使い分けると効率的です。

  • Action / Func:軽量で処理速度が速い。コードだけで完結させたいときに便利。
  • UnityEvent:Inspectorからイベントを登録したい場合に有効。デザイナーや非エンジニアでも設定可能。
  • event修飾子:外部から勝手に実行されないように制御したいときに必須。

小規模な処理はAction、プロトタイピングやUI連携はUnityEventといった使い分けがベストです。


5-3. 注意点とベストプラクティス

  • Invokeの安全呼び出し:必ず ?.Invoke() を使い、Null参照エラーを防ぐ
  • ラムダ式の乱用に注意:簡単ですが、RemoveListenerできないケースがあるので長期的な開発では関数化を推奨
  • イベントの登録解除:シーン遷移時などに解除しないとメモリリークや不具合の原因になる
  • 可視化の工夫:Inspectorやログでイベントの流れを追えるようにする

特に大規模なプロジェクトでは「イベントのつなぎ忘れ」「解除忘れ」がトラブルにつながりやすいです。
Odin Inspector や Editor Console Pro のような補助ツールを活用して、イベントの可視化・デバッグを行うのが安全な開発につながります。




6. まとめ

今回は、C#の delegateActionFunc、そしてUnity独自の UnityEvent を使ったカスタムイベントの作り方を解説しました。
一見難しそうに見えますが、ポイントを押さえればイベント処理はとてもシンプルに書けるようになります。

  • delegate:関数を変数のように扱える基本仕組み
  • Action / Func:より簡潔に使えるデリゲート型
  • event修飾子:外部からの不正な実行を防ぐ安全策
  • UnityEvent:Inspectorから直感的にイベント登録できる仕組み

これらを使い分けることで、スクリプト同士の結合度を下げ、保守性の高いプロジェクトを作ることができます。
特にUnityEventは「エンジニア以外でも設定できる」という強みがあるため、チーム開発やプロトタイピングで重宝します。

最後に、もっと体系的にC#とUnityのイベントシステムを学びたい方には、こちらの書籍がおすすめです。基本文法から応用パターンまで幅広く解説されており、イベント処理の理解をさらに深められます。

イベントの仕組みを理解して使いこなせるようになれば、ゲーム開発の幅は一気に広がります。ぜひ自分のプロジェクトでも試してみてくださいね!


あわせて読みたい

今回の記事とあわせて読むと、さらに理解が深まるおすすめの関連記事をピックアップしました。イベント処理やコード設計に関連する内容なので、ぜひチェックしてみてください。


よくある質問(FAQ)

Q
ActionとUnityEventはどちらを使えばいいの?
A

基本的にはActionの方が軽量で処理速度が速いので、コードだけで完結させたい場合におすすめです。
一方でUnityEventはInspectorから関数を登録できるので、非エンジニアやデザイナーと協力して作業する場合に便利です。
状況に応じて使い分けるのがベストです。

Q
Invokeを呼ぶときにエラーが出るのはなぜ?
A

Invoke()を呼ぶ際に、イベントに何も登録されていないとNull参照エラーが発生します。
このエラーを避けるために、必ず?.Invoke()を使って「登録があるときだけ呼び出す」ようにしましょう。

Q
UnityEventはパフォーマンス的に問題ない?
A

UnityEventはInspectorで設定できる分、Actionよりもわずかに処理が重くなります。
ただし、通常のゲーム開発ではほとんど気にならないレベルです。
頻繁に呼ばれる処理(Updateなど)ではActionUIやイベント設定を柔軟にしたい場合はUnityEventと使い分けるのが実践的です。

※当サイトはアフィリエイト広告を利用しています。リンクを経由して商品を購入された場合、当サイトに報酬が発生することがあります。

※本記事に記載しているAmazon商品情報(価格、在庫状況、割引、配送条件など)は、執筆時点のAmazon.co.jp上の情報に基づいています。
最新の価格・在庫・配送条件などの詳細は、Amazonの商品ページをご確認ください。

スポンサーリンク