Một mô hình debounce là một kỹ thuật lập trình ngăn chặn một hàm chạy quá nhiều lần hoặc một đầu vào kích hoạt nhiều lần. Các tình huống lập trình sau đây minh họa debounce như một thực tiễn tốt nhất.
Phát hiện va chạm
Giả sử bạn muốn tạo một phần bẫy nguy hiểm gây ra 10 sát thương khi bị chạm. Một cách triển khai ban đầu có thể sử dụng kết nối cơ bản BasePart.Touched và một hàm damagePlayer như sau:
Script - Damage Player
local part = script.Parent
local function damagePlayer(otherPart)
print(part.Name .. " đã va chạm với " .. otherPart.Name)
local humanoid = otherPart.Parent:FindFirstChildWhichIsA("Humanoid")
if humanoid then
humanoid.Health -= 10 -- Giảm sức khoẻ của người chơi
end
end
part.Touched:Connect(damagePlayer)
Trong khi có vẻ hợp lý ở cái nhìn đầu tiên, việc kiểm tra sẽ cho thấy rằng sự kiện Touched sẽ được kích hoạt nhiều lần liên tiếp nhanh chóng dựa trên những va chạm vật lý tinh tế.

Để tránh gây tổn thương quá mức khi tiếp xúc ban đầu, bạn có thể thêm một hệ thống debounce để thực thi thời gian hồi chiêu trên tổn thương thông qua một thuộc tính instance.
Script - Damage Player Using Debounce
local part = script.Parent
local RESET_TIME = 1
local function damagePlayer(otherPart)
print(part.Name .. " đã va chạm với " .. otherPart.Name)
local humanoid = otherPart.Parent:FindFirstChildWhichIsA("Humanoid")
if humanoid then
if not part:GetAttribute("Touched") then
part:SetAttribute("Touched", true) -- Đặt thuộc tính thành true
humanoid.Health -= 10 -- Giảm sức khoẻ của người chơi
task.wait(RESET_TIME) -- Chờ thời gian thiết lập lại
part:SetAttribute("Touched", false) -- Đặt lại thuộc tính
end
end
end
part.Touched:Connect(damagePlayer)
Kích hoạt âm thanh
Debounce cũng hữu ích khi làm việc với các hiệu ứng âm thanh, chẳng hạn như phát âm thanh khi hai phần va chạm (Touched), hoặc phát âm thanh trên sự kiện Activated khi người dùng tương tác với một nút trên màn hình. Trong cả hai trường hợp, việc gọi Sound:Play() bắt đầu phát âm thanh từ đầu và — không có hệ thống debounce — âm thanh có thể được phát nhiều lần liên tiếp nhanh chóng.
Để ngăn chặn âm thanh chồng chéo, bạn có thể sử dụng debounce bằng thuộc tính IsPlaying của đối tượng Sound:
Script - Play Collision Sound Using Debounce
local projectile = script.Parent
local function playSound()
-- Tìm âm thanh con trên phần
local sound = projectile:FindFirstChild("Impact")
-- Phát âm thanh chỉ khi nó chưa được phát
if sound and not sound.IsPlaying then
sound:Play()
end
end
projectile.Touched:Connect(playSound)
Script - Play Button Click Using Debounce
local button = script.Parent
local function onButtonActivated()
-- Tìm âm thanh con trên nút
local sound = button:FindFirstChild("Click")
-- Phát âm thanh chỉ khi nó chưa được phát
if sound and not sound.IsPlaying then
sound:Play()
end
end
button.Activated:Connect(onButtonActivated)
Hiệu ứng thu thập
Các trò chơi thường bao gồm những vật phẩm thu thập được trong thế giới 3D như bộ y tế, gói đạn và nhiều thứ khác. Nếu bạn thiết kế những vật phẩm thu thập này để giữ lại trong thế giới cho người chơi lấy đi nhiều lần, một khoảng thời gian "hồi chiêu" nên được thêm vào trước khi vật phẩm thu thập tự làm mới và kích hoạt lại.
Giống như phát hiện va chạm, bạn có thể quản lý trạng thái debounce với một thuộc tính instance, và trực quan hóa khoảng thời gian hồi chiêu bằng cách thay đổi thuộc tính Transparency của phần.
Script - Health Pickup Using 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) -- Đặt thuộc tính thành true
humanoid.Health += 25 -- Tăng sức khoẻ của người chơi
part.Transparency = 0.75 -- Làm cho phần bán trong suốt để chỉ ra trạng thái hồi chiêu
task.wait(COOLDOWN_TIME) -- Chờ thời gian hồi chiêu
part.Transparency = 0 -- Đặt lại phần về trong suốt hoàn toàn
part:SetAttribute("CoolingDown", false) -- Đặt lại thuộc tính
end
end
end
part.Touched:Connect(healPlayer)