跳到主要内容

设置 GES 监听器的执行顺序

TinyGiants
Unity Games & Tools Developer

伤害事件同时负责扣血和刷新 HUD 时,把两个监听器注册到同一优先级分层,给更新数据的监听器更高优先级,如果事件还混用了 Inspector 动作和 C# 回调,再按执行阶段核对完整顺序

在同一监听阶段设定优先级​

把扣血和 HUD 刷新都注册为 Priority 监听器,给扣血更高的数值

事件参数会原样传给每个回调,在写入生命值的回调中计算减伤

using TinyGiants.GES.Runtime;
using UnityEngine;

public sealed class DamageListeners : MonoBehaviour
{
[GameEventDropdown, SerializeField] private Int32GameEvent onPlayerDamaged;
[SerializeField] private int armor;
[SerializeField] private int health = 100;

private void OnEnable()
{
onPlayerDamaged.AddPriorityListener(ApplyDamage, priority: 100);
onPlayerDamaged.AddPriorityListener(RefreshHealthUI, priority: 25);
}

private void OnDisable()
{
onPlayerDamaged.RemovePriorityListener(ApplyDamage);
onPlayerDamaged.RemovePriorityListener(RefreshHealthUI);
}

private void ApplyDamage(int amount)
{
health = Mathf.Max(0, health - Mathf.Max(0, amount - armor));
}

private void RefreshHealthUI(int amount)
{
Debug.Log($"Health after {amount} raw damage: {health}");
}
}

顺序正确的 Demo 给数据写入和表现回调分配了不同优先级,HUD 读取的是扣血后的数值

按优先级执行的 Behavior

执行顺序出错时,HUD 会在扣血前读到旧的生命值

执行顺序出错的 Behavior

有依赖的回调用不同数值,多个事件共用一套顺序时,可以用 Model、View 等常量命名

核对事件的执行顺序​

阶段执行内容
1Basic 监听器,按注册顺序
2Inspector 动作,启用时执行
3Priority 监听器,数值从高到低
4Conditional 监听器,数值从高到低,调用每个回调前检查对应条件
5Persistent 监听器,数值从高到低
6Trigger 连接
7Chain 连接

优先级在同一阶段内生效,Basic 阶段的 HUD 会先于 Priority 阶段的扣血回调

把两者放进同一个 Priority 阶段,或在扣血写入后另发一个事件刷新 HUD

在 Game Event Monitor 打开该事件,进入 Listeners 检查回调注册在哪个阶段

Monitor 的 Listeners 列表

按事件参数筛选回调​

只在部分情况下执行的反应可以用 Conditional 监听器,Int32GameEvent 的条件接收一个 int

onPlayerDamaged.AddConditionalListener(
call: HandleCriticalHit,
condition: amount => amount > 50,
priority: 75);

// When the owner stops listening:
onPlayerDamaged.RemoveConditionalListener(HandleCriticalHit);

GameEvent<GameObject, int> 会把发送者和参数都传给条件与回调

onDamageFromSource.AddConditionalListener(
call: HandleBossDamage,
condition: (sender, amount) => sender != null && sender.CompareTag("Boss"),
priority: 75);

跨场景监听​

音频等贯穿游戏会话的服务可用 AddPersistentListener,持续监听 Demo 中的音频服务切换场景后仍能收到音效请求

Persistent 监听的 Behavior

private void Start()
{
DontDestroyOnLoad(gameObject);
onEnemyDied.AddPersistentListener(PlayDeathSound, priority: 10);
}

private void OnDestroy()
{
onEnemyDied.RemovePersistentListener(PlayDeathSound);
}

在 Demo 场景中找到持有回调的服务,根据它需要停止监听的时机解绑

若禁用服务时就要静音,可在 OnEnable 注册,在 OnDisable 解绑

Persistent 监听的场景配置

RemoveAllListeners() 清除 Basic、Priority 和 Conditional 监听器,移除 Persistent 监听器时调用 RemovePersistentListener

保留注册时用的回调​

移除方法回调时传入注册时的方法,移除 Lambda 时传入保存的委托

以下示例用 UnityAction<int> 保存 Int32GameEvent 的回调

private UnityEngine.Events.UnityAction<int> _handler;

private void OnEnable()
{
_handler = amount => health -= amount;
onPlayerDamaged.AddListener(_handler);
}

private void OnDisable()
{
onPlayerDamaged.RemoveListener(_handler);
}

🚀 全球开发者服务矩阵

🇨🇳 国区开发者社区

🌐 全球开发者社区

📧 支持与合作