Skip to content

委托、事件、Action

unity-csharp-delegate-event-action-system

核心理解

委托就是“能存方法的变量”。

c
public delegate void DamageHandler(int damage);

void PlayHitSound(int damage)
{
    Debug.Log("播放受击音效");
}

DamageHandler handler = PlayHitSound;
handler(10);

DamageHandler 规定:能放进来的方法必须是 void 返回值,并且有一个 int 参数。

Action 是什么

Action 是 C# 已经帮你定义好的常用委托,表示“没有返回值的方法”。

c
Action onDied;
Action<int> onHpChanged;
Action<int, int> onHpChangedWithOldNew;

所以很多时候你不用自己写:

c
public delegate void DieHandler();

直接写:

c
public Action OnDied;

event 是什么

event 是给委托加一层安全限制。

c
public event Action OnDied;

外部脚本只能:

c
health.OnDied += ShowGameOver;
health.OnDied -= ShowGameOver;

外部不能随便 Invoke,也不能直接 = null 清空。 也就是说:发布者自己触发事件,订阅者只能订阅或取消订阅。

Unity 常见写法

c
public class Health : MonoBehaviour
{
    public event Action<int, int> OnHpChanged;
    public event Action OnDied;

    private int hp = 100;

    public void TakeDamage(int damage)
    {
        int oldHp = hp;
        hp -= damage;

        OnHpChanged?.Invoke(oldHp, hp);

        if (hp <= 0)
        {
            OnDied?.Invoke();
        }
    }
}

订阅者:

c
void OnEnable()
{
    health.OnHpChanged += RefreshHpBar;
    health.OnDied += ShowGameOver;
}

void OnDisable()
{
    health.OnHpChanged -= RefreshHpBar;
    health.OnDied -= ShowGameOver;
}

记住这套关系

delegate:定义一种“方法形状”。 Action:C# 内置的无返回值委托。 Func:C# 内置的有返回值委托。 event:受保护的委托,只允许外部订阅和取消订阅。 UnityEvent:Unity 的可序列化事件,可以在 Inspector 里拖对象配置回调。

选择口诀

代码内部模块通信:优先 event Action。 需要在 Inspector 里配置:用 UnityEvent。 事件订阅了:记得在 OnDisable 里取消订阅。

参考链接

文章评价

读完这篇,留下你的看法

暂无审核通过的评价。

登录账号后才能评价。

本站访客数0总站访问量0本页访问量0