使用智能形状构建 OrbitRun | 第 6 部分:电池拾取物
在你希望玩家飞到的位置放置一个电池:山谷底部。收集电池可为计时器增加 8 秒。现在,一次漂亮的俯冲能为你争取更多时间,而不断加快的节奏也会让你更难抵达下一个山谷。
从第 5 部分继续,或从检查点资源包中打开 OrbitRun-18-rising-pace.tap。你可以使用项目中已有的面板图形和字体制作电池。
在图示中,REUSE 表示使用你已经添加的行为。如需回顾手势操作,请参阅第 1 部分中的行为连接指南。轻点图片可全尺寸查看。
19. 将电池放在山谷中
赛道每次运行都会变化,因此放置电池前,你需要先找到一个山谷。使用 Raycast Test 在三个相邻点采样地面。当中间点低于两侧时,就找到了低处。
先放置一个电池。玩家收集电池或飞过电池后,你可以将同一个对象移到另一个山谷。
观察倒计时增加 8 秒,并在收集电池时绿色电池消失。
制作电池
制作一个小巧明亮、在地面背景上醒目的拾取物:
- 将
orbit-panel添加到世界层,命名为 Battery,并缩小成一个徽章。为其设置鲜亮的色调,再在上方放置一个名为 Battery Label、文字为+8的标签。 - 使用居中锚点,这样图形和标签一起移动时就能对齐。将 Battery 设为 Static,禁用其碰撞,并在初始时隐藏这两个对象。放置行为会为它们选择位置。
- 在 Skimmer 的属性中添加
batteryActive=0。0 表示搜索山谷;1 表示将当前拾取物留在原位。
搜索前方地形
有关起点、终点、图层和命中输出的信息,请参阅 Raycast Test。当下方字段引用其他行为的结果时,请使用第 2 部分演示的数据输出拖放操作。
将这些行为添加到 Skimmer 上。按小图示的顺序操作:搜索、采样地面、放置电池,然后回收未被收集的电池。
先建立搜索链:
- Battery Search State (Get Attribute):Skimmer,
batteryActive - Battery Search Idle (If):Attribute Value 等于 0
- Battery Place Position (Get Position):Skimmer,关闭 Screen Coordinates
- Battery Next X (Add Values):Skimmer 的 X Position + 35
- Battery Left X (Subtract Values):Battery Next X 的结果 − 4
第一张连接指南将 Flight Tick 连接到 Battery Search State。现有的 0.05 秒计时器会频繁检查前方,即使速度不断提高,也能及时发现山谷。只有当 batteryActive 为 0 时,才会发射射线。
仅在没有激活的电池时向前搜索。
- 重用 Flight Tick。
- 添加名为 Battery Search State 的 Get Attribute。将 Flight Tick 上一个空闲的底部白色圆点连接到 Battery Search State。
- 添加名为 Battery Search Idle 的 If。将 Battery Search State 上一个空闲的底部白色圆点连接到 Battery Search Idle。
- 添加名为 Battery Place Position 的 Get Position。将 Battery Search Idle 底部(true)圆点连接到 Battery Place Position。
- 添加名为 Battery Next X 的 Add Values。将 Battery Place Position 上一个空闲的底部白色圆点连接到 Battery Next X。
- 添加名为 Battery Left X 的 Subtract Values。将 Battery Next X 上一个空闲的底部白色圆点连接到 Battery Left X。
接下来的两张指南会添加三个 Raycast Test 行为。它们都使用 Closest Object、Any Object、world layer 0、关闭 All Layers,以及 Position 目标类型。每条射线都从 Y 80 发射到 Y −40,垂直穿过赛道。起点和终点使用相同的 X:
- Battery Ray Left:Battery Left X 的结果
- Battery Ray Center:Battery Next X 的结果
- Battery Ray Right:Battery Right X 的结果;此值由 Battery Next X + 4 的 Add Values 计算得出
每条射线后面都添加一个 If,检查其 Intersected 输出是否等于 1。将检查命名为 Battery Left Hit、Battery Center Hit 和 Battery Right Hit。使用每项检查的 true 输出继续操作。如果任意射线未命中地面,搜索就会等待。
在第二张采样指南中配置两个山谷检查:
- Battery Low Left:Center 射线的 Y Position < Left 射线的 Y Position。
- Battery Low Right:Center 射线的 Y Position < Right 射线的 Y Position。
先测试左侧射线,再继续测试中间射线。
- 重用 Battery Left X。
- 添加名为 Battery Ray Left 的 Raycast Test。将 Battery Left X 上一个空闲的底部白色圆点连接到 Battery Ray Left。
- 添加名为 Battery Left Hit 的 If。将 Battery Ray Left 上一个空闲的底部白色圆点连接到 Battery Left Hit。
- 添加名为 Battery Ray Center 的 Raycast Test。将 Battery Left Hit 底部(true)圆点连接到 Battery Ray Center。
- 添加名为 Battery Center Hit 的 If。将 Battery Ray Center 上一个空闲的底部白色圆点连接到 Battery Center Hit。
将射线瞄准采样点的 X 坐标
放开后,Origin X 中会显示 Battery Next X · final value。用相同方法将结果拖入 Destination X。
右侧射线命中后,比较中间点和两侧的高度。
- 重用 Battery Center Hit。
- 添加名为 Battery Right X 的 Add Values。将 Battery Center Hit 底部(true)圆点连接到 Battery Right X。
- 添加名为 Battery Ray Right 的 Raycast Test。将 Battery Right X 上一个空闲的底部白色圆点连接到 Battery Ray Right。
- 添加名为 Battery Right Hit 的 If。将 Battery Ray Right 上一个空闲的底部白色圆点连接到 Battery Right Hit。
- 添加名为 Battery Low Left 的 If。将 Battery Right Hit 底部(true)圆点连接到 Battery Low Left。
- 添加名为 Battery Low Right 的 If。将 Battery Low Left 底部(true)圆点连接到 Battery Low Right。
放置并固定拾取物
放置指南从 Battery Low Right 的 true 输出继续。使用以下设置:
- Battery Ground Y (Add Values):Center 射线的 Y Position + 1.2
- Battery Lock (Set Attribute):Skimmer,
batteryActive= 1 - Battery Place (Move to Point):Battery;X = Center 射线的 X Position;Y = Battery Ground Y 的结果;持续时间 0,关闭 Screen Coordinates
- Battery Label Place (Move to Point):Battery Label;使用相同的 X 和 Y,持续时间 0,关闭 Screen Coordinates
- Battery Show (Set Visibility):Battery,Show Graphic
- Battery Label Show (Set Visibility):Battery Label,Show Graphic
停止搜索,将电池移到低处,然后显示它。
- 重用 Battery Low Right。
- 添加名为 Battery Ground Y 的 Add Values。将 Battery Low Right 底部(true)圆点连接到 Battery Ground Y。
- 添加名为 Battery Lock 的 Set Attribute。将 Battery Ground Y 上一个空闲的底部白色圆点连接到 Battery Lock。
- 添加名为 Battery Place 的 Move To Point。将 Battery Lock 上一个空闲的底部白色圆点连接到 Battery Place。
- 添加名为 Battery Label Place 的 Move To Point。将 Battery Place 上一个空闲的底部白色圆点连接到 Battery Label Place。
- 添加名为 Battery Show 的 Set Visibility。将 Battery Label Place 上一个空闲的底部白色圆点连接到 Battery Show。
- 添加名为 Battery Label Show 的 Set Visibility。将 Battery Show 上一个空闲的底部白色圆点连接到 Battery Label Show。
使用地面高度
放开后,Y position 中会显示 Battery Ground Y · final value。也将此结果用于 Battery Label Place 的 Y 字段。
1.2 m 的偏移量可让图形略高于碰撞表面。激活标记会在飞船靠近时锁定其位置,因此电池不会随着移动的扫描位置漂移。
回收未被收集的电池
使用下面的回收指南,并配置以下属性:
- Get Position,别名 Battery Position,目标为 Battery,关闭 Screen Coordinates。
- Subtract Values,别名 Battery Gap:Battery Position 的 X Position − 现有 HUD Position 的 X Position 输出。
- If,别名 Battery Missed:Battery Gap 的结果 < −6。
- Set Attribute,别名 Battery Deactivate:Skimmer,
batteryActive= 0。 - Set Visibility,别名 Battery Hide Cell,隐藏 Battery;接着使用 Battery Hide Label 隐藏 Battery Label。
当电池落在飞船后方超过 6 m 时,将其隐藏并允许再次搜索。
- 重用 Position。
- 添加名为 Battery Position 的 Get Position。将 Position 上一个空闲的底部白色圆点连接到 Battery Position。
- 添加名为 Battery Gap 的 Subtract Values。将 Battery Position 上一个空闲的底部白色圆点连接到 Battery Gap。
- 添加名为 Battery Missed 的 If。将 Battery Gap 上一个空闲的底部白色圆点连接到 Battery Missed。
- 添加名为 Battery Deactivate 的 Set Attribute。将 Battery Missed 底部(true)圆点连接到 Battery Deactivate。
- 添加名为 Battery Hide Cell 的 Set Visibility。将 Battery Deactivate 上一个空闲的底部白色圆点连接到 Battery Hide Cell。
- 添加名为 Battery Hide Label 的 Set Visibility。将 Battery Hide Cell 上一个空闲的底部白色圆点连接到 Battery Hide Label。
沿着山谷方向追踪一个电池。它应该固定在赛道上的那个位置。飞过它,观察它在落到飞船后方后消失;之后可以在另一个山谷放置下一个电池。收集功能会在第 20 步添加。
拾取物使用世界坐标,因此镜头缩放时它仍会留在赛道上。当 batteryActive 为 1 时,搜索会停止,电池会留在原位。
你可以调整搜索向前看的距离(35 m)或采样点之间的间距(4 m)。更改其中一项,观察下一个电池出现的位置。如果调整赛道的高度或位置,请确保每条射线的起点都高于山丘,终点都低于山谷。
20. 收集能量,并在能量耗尽时结束游戏
早期原型使用了固定的 Run Limit 计时器。必须移除该计时器,否则即使收集了电池,游戏也会在 90 秒时结束。
检测收集
仅在电池激活时检查是否收集。如果飞船足够接近,就增加奖励时间,并在下一次检查前隐藏电池。
使用以下设置:
- Battery Collect State:Skimmer,属性
batteryActive。 - Battery Collect Active:Attribute Value 等于 1。
- Battery Distance:Calculate Distance;Object A = Skimmer,Object B = Battery,开启 Compensate for Zoom。
- Battery Near:Battery Distance 的 Value < 2.5。
- Battery Bonus:自身结果 + 8,初始结果为 0。
- Battery Capacity:第一个数字为 90,第二个数字使用 Battery Bonus 的结果。
当电池处于激活状态,且飞船距离它小于 2.5 m 时,就可以收集。
- 重用 Flight Tick。
- 添加名为 Battery Collect State 的 Get Attribute。将 Flight Tick 上一个空闲的底部白色圆点连接到 Battery Collect State。
- 添加名为 Battery Collect Active 的 If。将 Battery Collect State 上一个空闲的底部白色圆点连接到 Battery Collect Active。
- 添加名为 Battery Distance 的 Calculate Distance。将 Battery Collect Active 底部(true)圆点连接到 Battery Distance。
- 添加名为 Battery Near 的 If。将 Battery Distance 上一个空闲的底部白色圆点连接到 Battery Near。
- 添加名为 Battery Bonus 的 Add Values。将 Battery Near 底部(true)圆点连接到 Battery Bonus。
将获得的秒数加到总能量中,并停用已收集的电池。
- 重用 Generate。
- 重用 Battery Bonus。
- 添加名为 Battery Capacity 的 Add Values。将 Generate 上一个空闲的底部白色圆点连接到 Battery Capacity。再将 Battery Bonus 上一个空闲的底部白色圆点连接到 Battery Capacity。
- 重用 Battery Deactivate。将 Battery Bonus 上一个空闲的底部白色圆点连接到 Battery Deactivate。
- 重用 Remaining。将 Battery Capacity 上一个空闲的底部白色圆点连接到 Remaining。
Battery Bonus 会累积获得的秒数。Battery Capacity 则保存初始能量和获得的能量之和。现有的 Seconds 行为会继续累计已用时间。
更新倒计时和结束条件
Timer 参考指南有助于区分重复执行的显示更新和你要替换的一次性运行时限计时器。
- 在 Remaining 中,将常量 A 值 90 替换为 Battery Capacity 的 result 输出。保留连接到 Seconds 的 result 输出的 B。
- 保留能量指南中的两条连接:Battery Capacity 连接到 Remaining,Battery Bonus 连接到 Battery Deactivate。拾取后会立即隐藏电池并将其标记为未激活,以免重复收集。随后搜索就能在另一个山谷放置电池。
- 删除旧的 Run Limit 计时器及其连接。
- 按照下面的结束指南,将 Energy Empty 设置为比较 Remaining 的结果是否 ≤ 0。重用 Finished,并保留 Remaining 现有的 Clock Text 连接。
- Battery Hide End 隐藏 Battery;Battery Label Hide End 隐藏 Battery Label。两者都使用 Set Visibility。按下面的结束指南连接它们。
在时钟中使用能量容量
放开后,First number (A) 中会显示 Battery Capacity · final value。第二个数字仍应引用 Seconds。
让 Remaining 在能量耗尽时触发 Finished。
- 重用 Remaining。
- 重用 Clock Text,并保留其与 Remaining 的现有连接。
- 添加名为 Energy Empty 的 If。将 Remaining 上一个空闲的底部白色圆点连接到 Energy Empty。
- 重用 Finished。将 Energy Empty 底部(true)圆点连接到 Finished。
- 添加名为 Battery Hide End 的 Set Visibility。将 Finished 上一个空闲的底部白色圆点连接到 Battery Hide End。
- 添加名为 Battery Label Hide End 的 Set Visibility。将 Battery Hide End 上一个空闲的底部白色圆点连接到 Battery Label Hide End。
现在,能量的计算关系如下:
剩余秒数 = 90 + 获得的电池秒数 − 已用秒数
重用 Finished 组。它已经会停止计时器和飞船、显示结果并检查最佳成绩。
让收集反馈清晰而有满足感
- 收集奖励指南会添加 Battery Chime (Play Sound)。使用与 Flow Sound 相同的设置和提示音资源。
- Battery Message (Change Label) 目标为 Flow Label,文字设为
+8s BATTERY。 - 按照下面收集奖励指南中的两个分支操作。
- 将 Battery Hide 设置为 1.3 秒、运行一次,并关闭 Start Immediately。按图示重用 Show Flow 和 Hide Flow。
- 断开 Velocity → Flow Check。这样反馈标签就专门用于显示电池消息,速度消息不会覆盖收集消息。拖尾和其他效果仍会保持激活。
- 将标题说明改为
按住向下俯冲。在山谷处松开。山谷电池可增加 8 秒飞行时间。将结果标题的初始文字改为 BATTERY EMPTY。个人最佳分支可能会将其替换为 NEW PERSONAL BEST。
播放提示音,并显示玩家获得了多少时间。
- 重用 Battery Bonus。
- 添加名为 Battery Chime 的 Play Sound。将 Battery Bonus 上一个空闲的底部白色圆点连接到 Battery Chime。
- 添加名为 Battery Message 的 Change Label。将 Battery Bonus 上一个空闲的底部白色圆点连接到 Battery Message。
- 重用 Show Flow。将 Battery Message 上一个空闲的底部白色圆点连接到 Show Flow。
- 添加名为 Battery Hide 的 Timer。将 Battery Message 上一个空闲的底部白色圆点连接到 Battery Hide。
- 重用 Hide Flow。将 Battery Hide 上一个空闲的底部白色圆点连接到 Hide Flow。
收集电池时观察时钟。时间应增加 8 秒,显示收集提示,并且电池只移除一次。之后可以在新的山谷中放置电池。获得额外能量后,继续飞过原本的 90 秒时限。下一次运行时,可以错过电池,等待能量耗尽;常规的结果画面和重玩流程仍应正常运行。
电池会增加 Battery Capacity。Seconds 仍会继续递增,因此第 5 部分的节奏也会继续加快。这样你就有理由追逐下一个电池,而抵达时的飞行难度也会更高。
按症状排查
- 电池不断增加秒数:Battery Bonus 必须触发 Battery Deactivate;收集逻辑必须受
batteryActive = 1控制 - 拾取效果只在某个缩放级别下正常:Calculate Distance 必须开启 Compensate for Zoom
- 收集电池后仍在正好 90 秒时结束:删除旧的 Run Limit 计时器;由 Energy Empty 触发 Finished
- 时钟立刻跳到负数:Generate 必须运行 Battery Capacity 以初始化 90 秒;Battery Bonus 和 Seconds 的初始值应为 0
- 标签移动了,但绿色电池留在原处:Battery Place 的目标必须是 Battery;Battery Label Place 的目标必须是 Battery Label
- 飞船无法碰到电池:检查三条射线的命中条件、两个低点比较条件,以及 1.2 米的表面偏移量
你的下一个实验
先玩几轮,再添加其他内容。你能否及时发现电池并调整方向?收集一个电池后,获得的时间够你抵达另一个吗?现在,这些问题比再添加一个功能更有价值。
准备扩展项目时,可以尝试在通往山谷的下坡路线上放置一小排电池。你需要准备少量可重复使用的对象,并确保每个电池只奖励一次。利用它们的位置引导玩家在合适的时机松开操作。

