Um padrão de desvio é uma técnica de codificação que impede que uma função seja executada muitas vezes ou que uma entrada seja acionada muitas vezes. Os seguintes scripts de exemplos ilustram o debounce como uma melhor prática.
Detectando Colisões
Suponha que você queira criar uma parte de armadilha perigosa que causa 10 danos quando tocada. Uma implementação inicial pode usar uma conexão básica de BasePart.Touched e uma função damagePlayer como esta:
Script - Danificar Jogador
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 -- Reduza a saúde do jogador
end
end
part.Touched:Connect(damagePlayer)
Embora lógico ao primeiro olhar, testes mostrarão que o evento Touched ativa várias vezes em sucessão rápida com base em colisões físicas sutis.
Para evitar causar dano excessivo em contatarinicial, você pode adicionar um sistema de desvio que impõe um período de cooldown de dano através de um atributo instância.
Script - Danificar o Jogador usando Debounce
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) -- Definir o atributo para verdadeiro
humanoid.Health -= 10 -- Reduza a saúde do jogador
task.wait(RESET_TIME) -- Aguarde pela duração de redefinição
part:SetAttribute("Touched", false) -- Redefinir atributo
end
end
end
part.Touched:Connect(damagePlayer)
Sons de Desencadeamento
O debounce também é útil quando trabalha com efeitos sonoros, como tocar um som quando duas peças colidem ( Class.BasePart.Touched|Touched) ou tocar um som no evento Class.GuiButton.Activated|Activado) quando um usuário interage com um botão na tela. Em ambos os casos, chamar
Para evitar sobreposição de som, você pode desbancar usando a propriedade IsPlaying do objeto Sound:
Script - Jogue o som de colisão usando o Debounce
local projectile = script.Parent
local function playSound()
-- Encontre o som da criança na peça
local sound = projectile:FindFirstChild("Impact")
-- Toque o som apenas se ele não estiver já tocando
if sound and not sound.IsPlaying then
sound:Play()
end
end
projectile.Touched:Connect(playSound)
Script - Clique no Botão de Jogar Usando Debounce
local button = script.Parent
local function onButtonActivated()
-- Encontre o som de filho no botão
local sound = button:FindFirstChild("Click")
-- Toque o som apenas se ele não estiver já tocando
if sound and not sound.IsPlaying then
sound:Play()
end
end
button.Activated:Connect(onButtonActivated)
Efeitos de Captura
Experiências geralmente incluem pickups coletáveis no mundo 3D, como kits médicos, pacotes de munição e muito mais. Se você projetar esses pickups para permanecer no mundo para que os jogadores possam agarrá-los uma e outra vez, um tempo de "cooldown" deve ser adicionado antes que o pickup seja atualizado e reativado.
Semelhante a detectar colisões, você pode gerenciar o estado de desvio com um atributo instância e visualizar o período de cooldown ao alterar o Transparency da peça.
Script - Coleta de Saúde Usando 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) -- Definir o atributo para verdadeiro
humanoid.Health += 25 -- Aumentar a saúde do jogador
part.Transparency = 0.75 -- Torne a peça semi-transparente para indicar o estado de espera
task.wait(COOLDOWN_TIME) -- Aguarde pela duração do cooldown
part.Transparency = 0 -- Redefinir a peça para ser totalmente opaca
part:SetAttribute("CoolingDown", false) -- Redefinir atributo
end
end
end
part.Touched:Connect(healPlayer)