跳到主要内容

在 Unity 中生成类型化事件资产

TinyGiants
Unity Games & Tools Developer

先按监听器需要的数据选择事件签名,Game Event Creator 会为事件及 Inspector 绑定生成具体类型,等 Unity 编译完成后,再把新事件资产赋给发送方和接收方

选择事件签名​

Game Event Creator 提供三种事件签名,按监听器所需的数据选择即可

Void 事件:GameEvent​

在关卡完成等只需发送信号的场景中,使用无参数的 GameEvent

Creator Parameterless

[GameEventDropdown, SerializeField] private GameEvent onLevelComplete;

public void CompleteLevel()
{
onLevelComplete.Raise();
}

单参数事件​

当响应需要收到数值时,例如读取更新后的分数,选择单参数事件

Creator Single

[GameEventDropdown, SerializeField] private Int32GameEvent onScoreChanged;

public void AddScore(int points)
{
currentScore += points;
onScoreChanged.Raise(currentScore);
}

Int32GameEvent 是继承 GameEvent<int> 的具体类,用它声明序列化事件字段,再在 Inspector 中赋予已创建的事件资产

Sender + Args 事件​

Game Event Creator 中的 Sender + Args 签名

多个对象会触发同一事件、回调又需要区分发送者时,选择 Sender + Args,例如同时传递受伤的 GameObject 和伤害数据

[GameEventDropdown, SerializeField] private GameObjectDamageInfoGameEvent onDamageTaken;

public void TakeDamage(DamageInfo info)
{
currentHealth -= info.amount;
onDamageTaken.Raise(gameObject, info);
}

内置事件签名​

包内包含 32 种已生成的单参数事件,覆盖 int、float、bool、string、Vector3、Color、GameObject 和 Transform 等常用类型,在 Creator 中可直接选用

Game Event Editor 中的基础参数类型

如果一次触发需要传递多个相关字段,例如伤害数值、伤害类型与命中点,把它们放进自定义数据类型,再为该类型创建事件

生成自定义事件类型​

在 Game Event Creator 中选择参数类型,如果该类型还没有生成对应代码,Creator 会先生成脚本,等 Unity 编译后再创建事件资产

创建单参数事件

以自定义的 DamageInfo 参数为例,事件脚本会生成 DamageInfoGameEvent : GameEvent<DamageInfo> 和可序列化的 DamageInfoGameEventActionEntry : GameEventSingleActionEntry<DamageInfo>,以及配套的 Raiser 和 Receiver 组件,Sender + Args 签名会生成对应的双参数类型

用 CodeGen 批量生成类型​

要预先为多种参数或 Sender + Args 组合生成代码,从 Game Event System 的 Tools & Utilities 打开代码生成工具,选好类型后执行生成

Game Event System 的代码工具

移除自定义参数类型前,先检查对应事件资产和场景的引用,再通过代码清理工具删除确认不再使用的生成文件

在伤害事件中传递自定义数据​

在项目的运行时代码中定义伤害参数,让回调一次收到伤害值、命中点和暴击状态

using System;
using UnityEngine;

namespace MyGame.Combat
{
[Serializable]
public struct DamageInfo
{
public float amount;
public Vector3 hitPoint;
public bool isCritical;
}
}

打开 Game Event Creator,选择单参数事件和 DamageInfo,命名为 OnDamageTaken,等编译后将新资产赋给脚本中的事件字段

using MyGame.Combat;
using TinyGiants.GES.Runtime;
using UnityEngine;

public class Health : MonoBehaviour
{
[GameEventDropdown, SerializeField] private DamageInfoGameEvent onDamageTaken;
private float currentHealth = 100f;

public void TakeDamage(DamageInfo info)
{
currentHealth -= info.amount;
onDamageTaken.Raise(info);
}
}

在 Game Event Behavior 的 Event Action 列表中选择接收对象与接收 DamageInfo 的方法,使用动态绑定传入事件参数,在 Play Mode 调用 TakeDamage 后,检查回调收到的伤害值是否与传入值一致

创建类型化事件