在基本腳本教程中,您已經編寫了單個部件的腳本以創建可玩的場景。使用之前的方法,如果您複製了部件,則也會有重複的腳本。這會使更新腳本變得繁瑣,因為更改必須逐個腳本進行。
在本教程中,將使用不同的模式來創建多個健康拾取物,並且只有一個副本的腳本來決定健康拾取物的行為。當拾取物被觸碰時,它將恢復玩家的健康,稍微淡出並在短時間內禁用。
設置
首先,您需要一個部件或模型作為拾取物。 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