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

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


恢复健康
首先,脚本需要恢复玩家的健康。这个模式您应该在致命熔岩教程中熟悉。
在 ServerScriptService 中,添加一个名为 PickupManager 的脚本。
在此脚本中,声明一个名为 MAX_HEALTH 的常量,值为 100。
创建一个名为 onTouchHealthPickup 的函数,参数为触碰拾取物的其他部件和拾取物本身。
local MAX_HEALTH = 100local function onTouchHealthPickup(otherPart, healthPickup)end在函数中,从 otherPart 的父级获取角色模型。接下来,检查它是否具有 Humanoid,使用 FindFirstChildWhichIsA()。
如果它有一个人形,设置他们的 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需要一个包装函数来在连接到 Touched 事件时将健康拾取物传递给 onTouchHealthPickup 函数。
在 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