在基本 scripting 教程中,你已經為可玩的場景編寫了單獨的部分。使用前面的方法,如果你複製這些部分,那麼你將會有重複的腳本。這樣更新腳本將變得繁瑣,因為所有更改必須一個腳本一個腳本地進行。
在本教程中,將使用不同的模式來創建多個健康回復道具,並且只有一份決定健康回復行為的腳本。當道具被觸碰時,它將恢復玩家的健康,稍微淡出,並在短時間內禁用。
設置
首先,你需要一個部件或模型用作回復道具。Showdown Town 範例世界中包含了許多健康回復道具,分佈在地圖的各處。

每個健康回復道具都是由兩個矩形部件組合而成,內部有一個綠色的 PointLight。它們都存放在工作空間中的一個名為 HealthPickups 的資料夾中,腳本將在這裡尋找它們。如果你在地圖中添加更多道具,確保它們也存放在這個資料夾中。


恢復健康
首先,腳本需要恢復玩家的健康。這種模式應該對你來說是熟悉的,來自 Deadly Lava 教程。
在 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 循環定義如下:

- 索引:這相當於普通 for 循環中的控制變數。
- 值:在循環迭代時,這將被填充為數組中的每個元素。將值變量命名為它實際包含的內容會是一個好主意。
- 數組:你希望迭代的數組傳遞給 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
現在測試你的代碼,你應該會發現健康回復道具可以恢復你的健康。你需要先對玩家造成傷害 - 嘗試站在出生點旁邊的通風口上。

健康條應該出現在右上角,當玩家被治療時會消失。
道具冷卻
目前,該道具將無限次地治療任何觸碰它的玩家。如果只允許一次拾取,並在再次使用之前有短暫的冷卻時間,將會更有效。
首先,你需要記錄道具是否處於冷卻期間。下面的模式應該為你熟悉,來自 Fade Trap - 這次,通過在健康回復道具上設置屬性來實現防重複。
在 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