創建一個生命值拾取

*此內容是使用 AI(Beta 測試版)翻譯,可能含有錯誤。若要以英文檢視此頁面,請按一下這裡

在基本腳本教學期間,您已經編寫了個別零件來創建可播放的場景。使用以前的方法,如果你複製零件,那麼你也會有複製的腳本。這將使更新腳本變得枯燥,因為必須一個接一指令碼地進行變更。

在這個教學中,會使用不同的模式來創建一系列健康提取,只有一個複製的腳本來決定健康提取行為。當撿起被觸碰時,會恢復玩家的生命值,稍微消失,並在短時間內被禁用。

設定

首先,你需要一個零件或模型來作為拾取使用。戰鬥城市示例世界 包含大量散落在地圖各處的生命拾取

Edit in Studio option from the experience's main page

每次生命拾取是由兩個長方形零件組成的聯盟,內部有綠色點光。它們都存在工作區的一個文件夾中,叫做 HealthPickups ,這是腳本會尋找它們的地方。如果您為地圖新增更多內容,您必須確保它們也存儲在此文件夾中。

恢復生命值

首先,腳本需要恢復玩家的生命值。這個模式應該對你來說很熟悉,因為它來自 致命熔岩 教學。

  1. 伺服器腳本服務 中,添加一個名為 PickupManager 的腳本。

  2. 在此指令碼中,宣言一個名為 MAX_HEALTH 的常量,並將值設為 100

  3. 創建一個名為 onTouchHealthPickup 的功能,其參數為另一部分觸碰拾取和拾取本身。


    local MAX_HEALTH = 100
    local function onTouchHealthPickup(otherPart, healthPickup)
    end
  4. 在功能中,從 otherPart 的父獲取角色模型。接下來,檢查是否有使用 HumanoidFindFirstChildWhichIsA()

  5. 如果它有人形,將其 生命值 屬性設為 MAX_HEALTH


    local MAX_HEALTH = 100
    local function onTouchHealthPickup(otherPart, healthPickup)
    local character = otherPart.Parent
    local humanoid = character:FindFirstChildWhichIsA("Humanoid")
    if humanoid then
    humanoid.Health = MAX_HEALTH
    end
    end

取得拾取文件夾

儲存健康拾取的文件夾可能在腳本執行時未載入到遊戲中。WaitForChild 可用於暫停腳本並在載入時獲得「HealthPickups」文件夾。

當在文件夾上呼叫時,GetChildren 功能將返回文件夾內容的一個數組。

  1. 在 MAX_HEALTH 下,宣言一個名為 healthPickupsFolder 的變量,並使用 WaitForChild 函數從工作區獲得 HealthPickups 文件夾。

  2. 創建名為 healthPickups 的變量來存儲在 healthPickupsFolder 上呼叫 GetChildren 函數的結果。


    local MAX_HEALTH = 100
    local healthPickupsFolder = workspace:WaitForChild("HealthPickups")
    local healthPickups = healthPickupsFolder:GetChildren()
    local function onTouchHealthPickup(otherPart, healthPickup)
    local character = otherPart.Parent
    local humanoid = character:FindFirstChildWhichIsA("Humanoid")
    if humanoid then
    humanoid.Health = MAX_HEALTH
    end
    end

使用 ipairs 循環

onTouchHealthPickup 需要在陣列中每次拾取生命值時呼叫。為了高效地執行此操作,將使用新的循環語法。

ipairs 是一個可以使用 for 循環來通過陣列的每個元素的函數。您不需要指定循環開始和結束的位置。使用 ipairs 的循環 A 定義如下:

  • 指數 : 這與正常循環中的控制變量相等。
  • :這將在迴圈執行時填充到陣列中的每個元素。命名變量值後,應該與它實際上包含的內容相同。
  • 陣列 : 你想要循環的陣列傳送到 ipairs 函數。

在下面的代碼中,你不需要對任何東西使用索引,因此可以使用 _ 留空。使用 **** 函數創建一個循環 ipairs ,傳遞 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 函數。

  1. 在 for 循環中,將觸發事件連接到一個匿名函數,其參數名稱為 otherPart

  2. 呼叫 onTouchHealthPickups 函數,傳遞兩個參數 otherParthealthPickup


    for _, healthPickup in ipairs(healthPickups) do
    healthPickup.Touched:Connect(function(otherPart)
    onTouchHealthPickup(otherPart, healthPickup)
    end)
    end

現在測試您的代碼,您應該發現生命拾取恢復了您的生命。您需要先傷害您的玩家 - 試著站在生成點旁邊的通風口上。

生命條應該出現在右上角,當玩家被治療時會消失。

拾取冷卻時間

目前,撿起將永久地治療任何觸碰它的玩家。在遊戲中,如果只能一次選擇,並在短時間內再次使用前需要冷卻時間,將會更有效。

首先,您需要記錄拾取是否處於冷卻期。下面的模式應該從 褪色陷阱 中熟悉 - 這次,減速將通過在生命拾取上設置一個特性來實現。

  1. 在 for 循環中,設置新的 屬性 稱為 "Enabled"true

  2. 將代碼包含在 onTouchHealthPickup 內的 if 聲明中,條件為 healthPickup:GetAttribute("Enabled")


    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
    end
    end
    end
    for _, healthPickup in ipairs(healthPickups) do
    healthPickup:SetAttribute("Enabled", true)
    healthPickup.Touched:Connect(function(otherPart)
    onTouchHealthPickup(otherPart, healthPickup)
    end)
    end

停用拾取

撿取應提供視覺反饋稱它已停用--一個常見的方法是讓它稍微透明。

  1. 在腳本頂部宣言三個常量 (請隨意調整每個值以符合你的需求):

    • ENABLED_TRANSPARENCY = 0.4
    • DISABLED_TRANSPARENCY = 0.9
    • COOLDOWN = 10

    local MAX_HEALTH = 100
    local ENABLED_TRANSPARENCY = 0.4
    local DISABLED_TRANSPARENCY = 0.9
    local COOLDOWN = 10
    local healthPickupsFolder = workspace:WaitForChild("HealthPickups")
  2. onTouchHealthPickup 中的 if 聲明中,將拾取的 Transparency 設為 DISABLED_TRANSPARENCY,並將 Enabled 屬性值設為 false。


    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)
    end
    end
    end
  3. 呼叫 task.wait() 函數,傳遞 COOLDOWN 作為要等待的數量。

  4. 設置 Transparency 返回 ENABLED_TRANSPARENCYEnabled 返回 true


    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

再次測試您的選取:您應該發現當您觸碰選取時,它會恢復您的生命值、變透明,然後回來準備再次使用。

如果您想使回饋對玩家在拾取時更具影響力,請嘗試在更改透明度時將點光源的亮度切割,以便在拾取時收集。

試試在自己的項目中使用這些生命選擇,或變更外觀和效果以提供不同類型的強化給您的玩家。

最終代碼


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