在虚幻引擎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:准备工作
-
新建蓝图:在内容浏览器中右键,创建一个蓝图类,父类选择Actor,命名为
BP_Countdown。 -
添加文本组件:打开
BP_Countdown,添加一个Text Render组件,用于显示倒计时数字。 -
创建UI控件(可选):如需更华丽的显示,可右键创建一个Widget Blueprint,在画布上添加一个
Text控件,命名为TimerText。
✨ 步骤2:创建倒计时核心逻辑
这里我们以最直观的 Set Timer by Event 为例。
-
创建变量:
-
在
BP_Countdown的变量面板,新建一个整数(Integer) 变量,命名为CountdownTime,默认值设为3(倒计时秒数)。 -
新建一个Timer Handle类型的变量,命名为
TimerHandle,用来管理定时器。
-
-
编写事件图表:
-
在事件图表中,从Event BeginPlay节点拖出连线,添加一个Set Timer by Event节点。
-
将
CountdownTime变量连接到节点的Time引脚。 -
勾选节点的Looping选项,实现每秒重复执行。
-
从节点的Event引脚拖出,选择Create Custom Event,并将其命名为
UpdateTimer。 -
将节点返回的Return Value赋值给
TimerHandle变量。
-
-
实现
UpdateTimer事件:-
从
UpdateTimer事件引脚的输出拖出,添加一个Branch节点。 -
分支条件:判断
CountdownTime是否大于0。 -
条件为真:将
CountdownTime变量减1。 -
条件为假:
-
调用Clear and Invalidate Timer by Handle节点,并用
TimerHandle变量作为输入,停止并清空定时器。 -
从Print String节点打印”GO!”或在屏幕上显示其他开始文字。
-
-
最终,蓝图核心逻辑的简化版如下:
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事件,该事件判断倒计时是否归零;如果归零,就清除定时器并执行“行动”,否则继续递减。
-
更新显示:
-
在
BP_Countdown中,从UpdateTimer事件的输出引线处添加Set Text (Text Render)节点,并用CountdownTime变量连接其Value引脚。 -
如果你使用的是Widget,可以创建一个函数,将
CountdownTime转换为文本后更新到TimerText控件中。
-
✨ 步骤3:实现重置功能
-
在变量面板中,创建一个Float(浮点数) 变量,命名为
ResetDelayTime,默认值设为3.0。 -
创建一个自定义事件,命名为
ResetTimer。 -
在
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,逻辑不变,但操作略有不同:
-
你需要在
BP_Countdown的函数面板中创建一个新函数,比如命名为UpdateTimerFunction,将所有逻辑写在这个函数里。 -
在事件图表中使用
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 Handle或Get Timer Elapsed Time by Handle节点,并输入你的
TimerHandle。 -
检查定时器是否存在:使用Does Timer Exist by Handle节点。这在尝试操作一个可能已被清除的定时器前进行安全检查非常有用。
-
💡 实用技巧与常见问题
-
为什么定时器没反应?
-
检查对象生命周期:如果拥有定时器的Actor在定时器触发前被销毁,定时器会自动取消,事件将不会执行。
-
检查
Time参数:Time参数必须大于0。如果设为0或负数,定时器会被清除。 -
检查逻辑执行流:确保Set Timer by Event节点确实被执行了。例如,在
BeginPlay中的节点一定会执行,但在一个未触发的自定义事件中的节点则不会。
-
-
性能优化:为什么应该避免使用Tick?
所有定时器节点内部的实现机制都优于使用Event Tick。Tick在60FPS下每秒运行60次,CPU负担沉重;而定时器每秒仅按需运行(例如1次),CPU占用极低。尤其对于倒计时、周期性生成敌人等逻辑,务必使用定时器。
💎 总结与最佳实践
-
Set Timer by Event-
优势:直观、安全(无拼写错误),调试方便,推荐作为首选方案。
-
适用场景:大多数通用逻辑,如倒计时、周期性攻击、UI更新等。
-
-
Set Timer by Function Name-
优势:灵活性高,可在运行时决定调用哪个函数。
-
适用场景:在C++ 中,或在高级动态设置中,你需要用一个字符串来决定定时器调用哪个函数时。
-
感谢您的来访,获取更多精彩文章请收藏本站。







暂无评论内容