How can I implement a debounce in this code

偶尔善良 提交于 2019-12-11 15:08:26

问题


My first thought was to ask on Roblox devforum but since imo they got a really messed up admission system, I might as well ask it here.

I've got a tool that shoots a block (wedge) to wherever the mouse is pointing when clicked. It also casts a ray and the block itself sets the health of any humanoid that makes contact with it to 0. But I have got no idea on how to actually implement a cooldown on the gun so you can't just literally spam blocks that kill anything that touches them arround. I think implementing a debounce here is the best option, but I got stuck with that since day 1 and I have no idea how to write it down correctly

I already tried with most of the things that I thought of after visiting this page Roblox dev page about Debounce, also read through some articles that had similar issues in the dev forum, but I can just spam blocks arround whatever I do.

The tool has just two parts (one being the handle) a localscript to wield the parts together, a localscript to catch the mouse position when clicked, two remote events to pass the info from the localscript to the server script and the following server script

local tool = script.Parent
local clickEvent = tool.ClickEvent
local clickEventConnection
local Players = game:GetService("Players")
local Teams = game:GetService("Teams")

--Function that creates the part with a touched listener that kills any humanoid that comes into contact with said block

local function createPart(location)
  local part = Instance.new("WedgePart")
  part.CFrame = location
  part.Parent = workspace
  part.BrickColor = BrickColor.new("Black")
  part.Touched:connect(function(hit)
    if hit.Parent then 
        local hum = hit.Parent:FindFirstChild("Humanoid")
        if hum then
            hum.Health = 0
        end
    end
end)
  game:GetService("Debris"):AddItem(part, 2)
end

--With the information on the click position of the localscript, this function creates a ray and a beam that accompanies the block, as well as executing the createpart() function on said location

local function onClick(player, clickLocation, ignore)
  createPart(clickLocation)
  local ray = Ray.new(
    tool.Handle.CFrame.p,                           
   (clickLocation.p - tool.Handle.CFrame.p).unit * 500 
) 
local hit, position, normal = workspace:FindPartOnRay(ray, player.Character, ignore)
local beam = Instance.new("Part", workspace)

        if player.Team ==  Teams["Blue Team"] then
            beam.BrickColor = BrickColor.new("Bright blue")
        elseif player.Team ==  Teams["Red Team"] then
            beam.BrickColor = BrickColor.new("Bright red")
        else
            beam.BrickColor = BrickColor.new("Ghost grey")
        end
        beam.FormFactor = "Custom"
        beam.Material = "Neon"
        beam.Transparency = 0.25
        beam.Anchored = true
        beam.Locked = true
        beam.CanCollide = false

        local distance = (tool.Handle.CFrame.p - position).magnitude
        beam.Size = Vector3.new(0.3, 0.3, distance)
        beam.CFrame = CFrame.new(tool.Handle.CFrame.p, position) * CFrame.new(0, 0, -distance / 2)

        game:GetService("Debris"):AddItem(beam, 1)
end

--subscribing onclick() when equiping the weapon and unsubscribig when unequipping it
local function onEquip()
  clickEventConnection = clickEvent.OnServerEvent:connect(onClick)
end

local function onUnequip()
  clickEventConnection:disconnect()
end

tool.Equipped:connect(onEquip)
tool.Unequipped:connect(onUnequip)

I just wanted to make a 'cooldown' so a block can be fired each 3 seconds. As is, you can just spam as much as you like to


回答1:


A simple way to debounce the clicks is to use a variable to decide whether to quickly escape from a function.

You can modify your onClick function so it does not execute if a cooldown is still in place :

-- make a cooldown tracker
local isGunOnCooldown = false
local cooldownTime = 3.0 --seconds

local function onClick(player, clickLocation, ignore)
    -- debounce any spammed clicks
    if isGunOnCooldown then
        return
    end

    -- put the gun on cooldown
    isGunOnCooldown = true

    -- fire a bullet
    createPart(clickLocation)
    local ray = Ray.new(
        tool.Handle.CFrame.p,                           
        (clickLocation.p - tool.Handle.CFrame.p).unit * 500)
    local hit, position, normal = workspace:FindPartOnRay(ray, player.Character, ignore)
    local beam = Instance.new("Part", workspace)

    if player.Team ==  Teams["Blue Team"] then
        beam.BrickColor = BrickColor.new("Bright blue")
    elseif player.Team ==  Teams["Red Team"] then
        beam.BrickColor = BrickColor.new("Bright red")
    else
        beam.BrickColor = BrickColor.new("Ghost grey")
    end
    beam.FormFactor = "Custom"
    beam.Material = "Neon"
    beam.Transparency = 0.25
    beam.Anchored = true
    beam.Locked = true
    beam.CanCollide = false

    local distance = (tool.Handle.CFrame.p - position).magnitude
    beam.Size = Vector3.new(0.3, 0.3, distance)
    beam.CFrame = CFrame.new(tool.Handle.CFrame.p, position) * CFrame.new(0, 0, -distance / 2)

    game:GetService("Debris"):AddItem(beam, 1)

    -- start the gun's cooldown and reset it
    spawn(function()
        wait(cooldown)
        isGunOnCooldown = false
    end)
end


来源:https://stackoverflow.com/questions/55797746/how-can-i-implement-a-debounce-in-this-code

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!