在基本脚本编写教程中,您已经为可玩场景编写了单个部件的脚本。使用先前的方法,如果您复制部件,则会产生重复脚本。这将使更新脚本变得繁琐,因为必须逐个脚本进行更改。
在本教程中,将使用不同的模式创建多个生命值拾取物,只需一个确定生命值拾取物行为的脚本副本。当拾取物被触碰时,它将恢复玩家的生命值,稍微消退并在短时间内禁用。
设置
首先,您需要一个部件或模型来用作拾取物。Showdown Town 示例世界包括地图上分布着大量生命值拾取物。

每个生命值拾取物是两个矩形部件的联合体,内部有一个绿色的 PointLight。它们都存储在名为 HealthPickups 的工作区文件夹中,脚本将在此文件夹中查找它们。如果您向地图中添加更多内容,确保它们也存储在此文件夹中。


恢复生命值
首先,脚本需要恢复玩家的生命值。这个模式应该对您在致命熔岩教程中很熟悉。
在 ServerScriptService 中,添加一个名为 PickupManager 的脚本。
在该脚本中,声明一个名为 MAX_HEALTH 的常量,值为 100。
创建一个名为 onTouchHealthPickup 的函数,参数为触碰拾取物的另一个部件和拾取物本身。
local MAX_HEALTH = 100local function onTouchHealthPickup(otherPart, healthPickup)end在函数中,从 otherPart 的父级获取角色模型。接下来,检查其是否具有 Humanoid,使用 FindFirstChildWhichIsA()。
如果它有一个 humanoid,将它的 Health 属性设置为 MAX_HEALTH。
local MAX_HEALTH = 100local function onTouchHealthPickup(otherPart, healthPickup)local character = otherPart.Parentlocal humanoid = character:FindFirstChildWhichIsA("Humanoid")if humanoid thenhumanoid.Health = MAX_HEALTHendend
获取拾取物文件夹
在脚本运行时,存放生命值拾取物的文件夹可能尚未加载到体验中。可以使用 WaitForChild 暂停脚本并在加载时获取 HealthPickups 文件夹。
当在文件夹上调用时,GetChildren 函数将返回该文件夹内容的数组。
在 MAX_HEALTH 下,声明一个名为 healthPickupsFolder 的变量,并使用 WaitForChild 函数从工作区获取 HealthPickups 文件夹。
创建一个名为 healthPickups 的变量,以存储在 healthPickupsFolder 上调用 GetChildren 函数的结果。
local MAX_HEALTH = 100local healthPickupsFolder = workspace:WaitForChild("HealthPickups")local healthPickups = healthPickupsFolder:GetChildren()local function onTouchHealthPickup(otherPart, healthPickup)local character = otherPart.Parentlocal humanoid = character:FindFirstChildWhichIsA("Humanoid")if humanoid thenhumanoid.Health = MAX_HEALTHendend
使用 ipairs 循环
onTouchHealthPickup 需要为数组中的每个生命值拾取物调用。为了高效做到这一点,将使用一种新的循环语法。
ipairs 是一个可以与 for 循环一起使用的函数,用于遍历数组的每个元素。您不需要指定循环的开始和结束位置。使用 ipairs 的 for 循环定义如下:

- Index: 这相当于常规 for 循环中的控制变量。
- Value: 当循环迭代时,这将用数组中的每个元素填充。根据实际内容给值变量命名是个好主意。
- Array: 您想遍历的数组作为参数传递给 ipairs 函数。
在以下代码中,您不需要索引,因此可以使用 _ 留空。使用 ipairs 函数创建一个 for 循环,传递 healthPickups。
local function onTouchHealthPickup(otherPart, healthPickup)
local character = otherPart.Parent
local humanoid = character:FindFirstChildWhichIsA("Humanoid")
if humanoid then
humanoid.Health = MAX_HEALTH
end
end
for _, healthPickup in ipairs(healthPickups) do
end
需要一个包装函数来将生命值拾取物传递给 onTouchHealthPickup 函数,以便连接到 Touched 事件。
在 for 循环中,将 Touched 事件连接到一个匿名函数,参数叫 otherPart。
调用 onTouchHealthPickups 函数,传递 otherPart 参数和 healthPickup。
for _, healthPickup in ipairs(healthPickups) dohealthPickup.Touched:Connect(function(otherPart)onTouchHealthPickup(otherPart, healthPickup)end)end
现在测试你的代码,您应该发现生命值拾取物可以恢复您的生命值。您需要先对玩家造成伤害 — 尝试站在出生点旁边的通风口上。

右上角应该会出现一个生命条,玩家被治疗时会消失。
拾取物冷却时间
当前,拾取物可以无限期治疗触碰它的任何玩家。如果它只能被拾取一次,且在再次使用之前有短暂的冷却时间,效果会更好。
首先,您需要记录拾取物是否在冷却期间。下面的模式应与 渐隐陷阱 中熟悉 - 此次,通过为生命值拾取物设置一个属性来实现去抖动。
在 for 循环中,将一个新的 属性 设置为 "Enabled" 为 true。
将 onTouchHealthPickup 中的代码包裹在一个 if 语句中,条件为 healthPickup:GetAttribute("Enabled")。
local function onTouchHealthPickup(otherPart, healthPickup)if healthPickup:GetAttribute("Enabled") thenlocal character = otherPart.Parentlocal humanoid = character:FindFirstChildWhichIsA("Humanoid")if humanoid thenhumanoid.Health = MAX_HEALTHendendendfor _, healthPickup in ipairs(healthPickups) dohealthPickup:SetAttribute("Enabled", true)healthPickup.Touched:Connect(function(otherPart)onTouchHealthPickup(otherPart, healthPickup)end)end
禁用拾取物
拾取物应提供视觉反馈,表明它被禁用 - 常见的指示方法是使其稍微透明。
在脚本顶部声明三个常量(可以根据自己的喜好调整每个值):
- ENABLED_TRANSPARENCY = 0.4
- DISABLED_TRANSPARENCY = 0.9
- COOLDOWN = 10
local MAX_HEALTH = 100local ENABLED_TRANSPARENCY = 0.4local DISABLED_TRANSPARENCY = 0.9local COOLDOWN = 10local healthPickupsFolder = workspace:WaitForChild("HealthPickups")在 onTouchHealthPickup 的 if 语句中,将拾取物的 Transparency 设置为 DISABLED_TRANSPARENCY,并将 Enabled 属性的值设置为 false。
local function onTouchHealthPickup(otherPart, healthPickup)if healthPickup:GetAttribute("Enabled") thenlocal character = otherPart.Parentlocal humanoid = character:FindFirstChildWhichIsA("Humanoid")if humanoid thenhumanoid.Health = MAX_HEALTHhealthPickup.Transparency = DISABLED_TRANSPARENCYhealthPickup:SetAttribute("Enabled", false)endendend调用 task.wait() 函数,传递 COOLDOWN 作为等待的时间。
将 Transparency 设置回 ENABLED_TRANSPARENCY,将 Enabled 设置回 true。
local function onTouchHealthPickup(otherPart, healthPickup)if healthPickup:GetAttribute("Enabled") thenlocal character = otherPart.Parentlocal humanoid = character:FindFirstChildWhichIsA("Humanoid")if humanoid thenhumanoid.Health = MAX_HEALTHhealthPickup.Transparency = DISABLED_TRANSPARENCYhealthPickup:SetAttribute("Enabled", false)task.wait(COOLDOWN)healthPickup.Transparency = ENABLED_TRANSPARENCYhealthPickup:SetAttribute("Enabled", true)endendend
再次测试您的拾取物:您应该发现,当您触碰拾取物时,它可以恢复您的生命值,变透明,然后再次可用。
如果您希望在收集拾取物时为玩家提供更明显的反馈,请尝试在您更改透明度时降低拾取物中 PointLight 的亮度。
尝试在您自己的项目中使用这些生命值拾取物,或者更改外观和效果,为您的玩家提供不同的增益。
最终代码
local MAX_HEALTH = 100
local ENABLED_TRANSPARENCY = 0.4
local DISABLED_TRANSPARENCY = 0.9
local COOLDOWN = 10
local healthPickupsFolder = workspace:WaitForChild("HealthPickups")
local healthPickups = healthPickupsFolder:GetChildren()
local function onTouchHealthPickup(otherPart, healthPickup)
if healthPickup:GetAttribute("Enabled") then
local character = otherPart.Parent
local humanoid = character:FindFirstChildWhichIsA("Humanoid")
if humanoid then
humanoid.Health = MAX_HEALTH
healthPickup.Transparency = DISABLED_TRANSPARENCY
healthPickup:SetAttribute("Enabled", false)
task.wait(COOLDOWN)
healthPickup.Transparency = ENABLED_TRANSPARENCY
healthPickup:SetAttribute("Enabled", true)
end
end
end
for _, healthPickup in ipairs(healthPickups) do
healthPickup:SetAttribute("Enabled", true)
healthPickup.Touched:Connect(function(otherPart)
onTouchHealthPickup(otherPart, healthPickup)
end)
end