虚幻引擎Set Timer by Event / by Function Name 节点

在虚幻引擎5的蓝图中,Set Timer by Event 和 Set Timer by Function Name 是两种核心的定时器节点。它们的主要区别在于:前者直接将逻辑连接到一个自定义事件上,更加直观;后者则通过一个字符串名称来引用一个函数或事件,在需要动态决定调用哪个函数时更加灵活,但更容易因名称输入错误而出错

下面是两个节点的核心参数:

参数 说明
Time 定时器触发的间隔时间,单位为秒
Looping 决定定时器是循环执行还是只执行一次
Initial Start Delay 可选,设置定时器启动前的初始延迟时间
Max Once Per Frame 若帧率极低导致在一帧内该被触发多次,勾选此项后可强制只执行一次
Return Value 输出一个 Timer Handle(定时器句柄),用于后续暂停、恢复或清除此定时器

接下来,我们将通过一个完整的游戏倒计时案例,来学习如何在实际项目中使用这两个节点。

💣 完整案例:可重置的游戏倒计时

我们将创建一个倒计时系统,在游戏开始时显示”3…2…1…GO!”。包含创建定时器、更新UI和处理重置的逻辑。

✨ 步骤1:准备工作

  1. 新建蓝图:在内容浏览器中右键,创建一个蓝图类,父类选择Actor,命名为BP_Countdown

  2. 添加文本组件:打开BP_Countdown,添加一个Text Render组件,用于显示倒计时数字。

  3. 创建UI控件(可选):如需更华丽的显示,可右键创建一个Widget Blueprint,在画布上添加一个Text控件,命名为TimerText

✨ 步骤2:创建倒计时核心逻辑

这里我们以最直观的 Set Timer by Event 为例。

  1. 创建变量

    • BP_Countdown变量面板,新建一个整数(Integer) 变量,命名为CountdownTime,默认值设为3(倒计时秒数)。

    • 新建一个Timer Handle类型的变量,命名为TimerHandle,用来管理定时器。

  2. 编写事件图表

    • 事件图表中,从Event BeginPlay节点拖出连线,添加一个Set Timer by Event节点。

    • CountdownTime变量连接到节点的Time引脚。

    • 勾选节点的Looping选项,实现每秒重复执行。

    • 从节点的Event引脚拖出,选择Create Custom Event,并将其命名为UpdateTimer

    • 将节点返回的Return Value赋值给TimerHandle变量。

  3. 实现UpdateTimer事件

    • UpdateTimer事件引脚的输出拖出,添加一个Branch节点。

    • 分支条件:判断CountdownTime是否大于0

    • 条件为真:将CountdownTime变量减1。

    • 条件为假

      • 调用Clear and Invalidate Timer by Handle节点,并用TimerHandle变量作为输入,停止并清空定时器

      • Print String节点打印”GO!”或在屏幕上显示其他开始文字。

最终,蓝图核心逻辑的简化版如下:

text
Event BeginPlay -> Set Timer by Event (Time: CountdownTime, Looping: true) -> 赋值给 TimerHandle
                     Event: UpdateTimer

                     UpdateTimer -> Branch (Condition: CountdownTime > 0)
                         | (True)
                         CountdownTime = CountdownTime - 1
                         | (False)
                         Clear and Invalidate Timer by Handle (TimerHandle)
                         Print String "GO!"

此逻辑的核心思想是:定时器每秒触发UpdateTimer事件,该事件判断倒计时是否归零;如果归零,就清除定时器并执行“行动”,否则继续递减。

  1. 更新显示

    • BP_Countdown中,从UpdateTimer事件的输出引线处添加Set Text (Text Render)节点,并用CountdownTime变量连接其Value引脚。

    • 如果你使用的是Widget,可以创建一个函数,将CountdownTime转换为文本后更新到TimerText控件中。

✨ 步骤3:实现重置功能

  1. 变量面板中,创建一个Float(浮点数) 变量,命名为ResetDelayTime,默认值设为3.0

  2. 创建一个自定义事件,命名为ResetTimer

  3. ResetTimer内部,放置以下节点:

    • Clear and Invalidate Timer by Handle:用TimerHandle作为输入,停止当前倒计时

    • CountdownTime变量设置回默认值(如3)。

    • 设置新的Set Timer by Event节点,参数与第二步相同。

这样,当你想重置倒计时时,只需调用ResetTimer自定义事件即可。

✨ 步骤4:对比Set Timer by Function Name实现

如果使用Set Timer by Function Name,逻辑不变,但操作略有不同:

  1. 你需要在BP_Countdown函数面板中创建一个新函数,比如命名为UpdateTimerFunction,将所有逻辑写在这个函数里

  2. 在事件图表中使用Set Timer by Function Name节点,在它的Function Name引脚上输入"UpdateTimerFunction"字符串

主要区别就在于Event版本更直观,Function Name版本在需要动态指定函数名时更灵活,但两者在功能上完全等价。

🛠️ 管理与操作

掌握定时器的管理同样是关键。

  • 暂停与恢复

    • 暂停:使用Pause Timer by Handle节点,输入你的TimerHandle变量。

    • 恢复:使用UnPause Timer by Handle节点,输入你的TimerHandle变量

  • 清理与重置

    • 清理并失效:推荐使用Clear and Invalidate Timer by Handle。它不仅能清空定时器,还能使TimerHandle变量失效,以防意外使用

    • 重置定时器:可以对同一个TimerHandle再次调用Set Timer by Event。这样做会自动清除原有定时器,并用新参数重新开始计时

  • 定时器句柄的高级用法

    • 查询剩余/经过时间:使用Get Timer Remaining Time by HandleGet Timer Elapsed Time by Handle节点,并输入你的TimerHandle

    • 检查定时器是否存在:使用Does Timer Exist by Handle节点。这在尝试操作一个可能已被清除的定时器前进行安全检查非常有用

💡 实用技巧与常见问题

  • 为什么定时器没反应?

    1. 检查对象生命周期:如果拥有定时器的Actor在定时器触发前被销毁,定时器会自动取消,事件将不会执行

    2. 检查Time参数Time参数必须大于0。如果设为0或负数,定时器会被清除

    3. 检查逻辑执行流:确保Set Timer by Event节点确实被执行了。例如,在BeginPlay中的节点一定会执行,但在一个未触发的自定义事件中的节点则不会。

  • 性能优化:为什么应该避免使用Tick?
    所有定时器节点内部的实现机制都优于使用Event TickTick在60FPS下每秒运行60次,CPU负担沉重;而定时器每秒仅按需运行(例如1次),CPU占用极低。尤其对于倒计时、周期性生成敌人等逻辑,务必使用定时器

💎 总结与最佳实践

  • Set Timer by Event

    • 优势:直观、安全(无拼写错误),调试方便,推荐作为首选方案。

    • 适用场景:大多数通用逻辑,如倒计时、周期性攻击、UI更新等。

  • Set Timer by Function Name

    • 优势:灵活性高,可在运行时决定调用哪个函数。

    • 适用场景:在C++ 中,或在高级动态设置中,你需要用一个字符串来决定定时器调用哪个函数时

感谢您的来访,获取更多精彩文章请收藏本站。

THE END
喜欢就支持一下吧
点赞12 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容