取消模式模式

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

一個 去抖動 模式是一種防止函數過多運行或輸入多次發生的編碼技巧。以下的腳本場景展示了將延遲視為最佳實踐。

偵測碰撞

假設您想創建一個危險陷阱零件,當觸碰時會造成 10 傷害。初始實裝可能會使用基本的 BasePart.Touched 連線和一個 damagePlayer 功能像這樣:

腳本 - 傷害玩家

local part = script.Parent
local function damagePlayer(otherPart)
print(part.Name .. " collided with " .. otherPart.Name)
local humanoid = otherPart.Parent:FindFirstChildWhichIsA("Humanoid")
if humanoid then
humanoid.Health -= 10 -- 減少玩家生命值
end
end
part.Touched:Connect(damagePlayer)

雖然在第一印象上是有道理的,但測試會顯示出 Touched 事件在快速疊加的情況下多次發生細微的物理碰撞,導致多次發生。

為了避免在初次聯絡時造成過度損壞,您可以添加一個延遲系統,強制通過 實例特性 對損壞進行冷卻期。

腳本 - 使用減速來傷害玩家

local part = script.Parent
local RESET_TIME = 1
local function damagePlayer(otherPart)
print(part.Name .. " collided with " .. otherPart.Name)
local humanoid = otherPart.Parent:FindFirstChildWhichIsA("Humanoid")
if humanoid then
if not part:GetAttribute("Touched") then
part:SetAttribute("Touched", true) -- 將特性設為真值
humanoid.Health -= 10 -- 減少玩家生命值
task.wait(RESET_TIME) -- 等待重置時間
part:SetAttribute("Touched", false) -- 重設特性
end
end
end
part.Touched:Connect(damagePlayer)

觸發聲音

減速也適用於處理聲音效果,例如當兩個部分碰撞時播放聲音(Touched),或當使用者與屏幕上的按鈕互動時播放聲音(Activated)的Sound:Play() 開始從其軌道的開頭播放,而且沒有延遲系統,聲音可能會在短時間內多次快速播放。

若要防止聲音重疊,您可以使用 IsPlaying 物件的 Sound 屬性來降低延遲:

腳本 - 使用 Debounce 播放碰撞聲音

local projectile = script.Parent
local function playSound()
-- 在零件上尋找兒子聲音
local sound = projectile:FindFirstChild("Impact")
-- 僅在尚未播放時播放聲音
if sound and not sound.IsPlaying then
sound:Play()
end
end
projectile.Touched:Connect(playSound)
腳本 - 使用減速來點擊播放按鈕

local button = script.Parent
local function onButtonActivated()
-- 在按鈕上尋找兒子聲音
local sound = button:FindFirstChild("Click")
-- 僅在尚未播放時播放聲音
if sound and not sound.IsPlaying then
sound:Play()
end
end
button.Activated:Connect(onButtonActivated)

拾取效果

經驗通常會包括在 3D 世界中的收藏品拾取,例如醫療包、彈藥包和更多。如果您設計這些拾取點留在世界上,讓玩家再次拾取和再次激活,那麼在拾取刷新和重新啟用之前應該添加一段"冷卻"時間。

偵測碰撞 類似,您可以使用 實例特性 來管理延遲狀態,並透過修改零件的 Transparency 來視覺化冷卻期。

腳本 - 使用 Debounce 撿取生命值

local part = script.Parent
part.Anchored = true
part.CanCollide = false
local COOLDOWN_TIME = 5
local function healPlayer(otherPart)
local humanoid = otherPart.Parent:FindFirstChildWhichIsA("Humanoid")
if humanoid then
if not part:GetAttribute("CoolingDown") then
part:SetAttribute("CoolingDown", true) -- 將特性設為真值
humanoid.Health += 25 -- 增加玩家生命值
part.Transparency = 0.75 -- 使零件部分半透明,以指示冷卻狀態
task.wait(COOLDOWN_TIME) -- 等待冷卻時間
part.Transparency = 0 -- 將零件重置為完全不透明
part:SetAttribute("CoolingDown", false) -- 重設特性
end
end
end
part.Touched:Connect(healPlayer)