Hello I am creating a ability system which does something after a key is pressed however it prints the output 5 times and fires the event five times.
The local script is inside the character model disabled then enables once spawning as the character and this is the only place where it is.
Here is the Local script:
> --Basic Witch Abilities
>
> --Telekinetic Push
> task.spawn(function()
> local UIS = game:GetService("UserInputService")
> local Cooldown = 20
> local Debounce = false
> local Player = game.Players.LocalPlayer
> local Character = Player.Character
> local Mouse = Player:GetMouse()
>
> UIS.InputBegan:Connect(function(key, IsTyping)
> if key.KeyCode == Enum.KeyCode.C then
> if not IsTyping then
> if Mouse.Target.Parent:FindFirstChildWhichIsA("Humanoid") then
> if (Mouse.Target.Parent.HumanoidRootPart.Position - Character.HumanoidRootPart.Position).Magnitude < 10 then
> if Debounce == false then
> Debounce = true
> print(Mouse.Target.Parent)
> game.ReplicatedStorage.Remotes.Abilities:FireServer("Basic Telekinetic Push", Mouse.Target.Parent)
> wait(Cooldown)
> Debounce = false
> end
> else
> if Debounce == true then
> print(Cooldown)
> end
> end
> else
> if (Mouse.Target.Parent.HumanoidRootPart.Position - Character.HumanoidRootPart.Position).Magnitude > 10 then
> print("To far from Target")
> end
> end
> end
> end
> end)
> end)
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local UserInputService = game:GetService("UserInputService")
local Cooldown = 20
local LastAbilityTime = 0
local Player = Players.LocalPlayer
local Character = Player.Character
local Mouse = Player:GetMouse()
UserInputService.InputBegan:Connect(function(Input, GameProcessedEvent)
if GameProcessedEvent then return end
if Input.KeyCode == Enum.KeyCode.C then
local CurrentTime = os.clock()
local TimeSinceLastAbility = CurrentTime - LastAbilityTime
if TimeSinceLastAbility >= Cooldown then
local Target = Mouse.Target
if Target and Target.Parent and Target.Parent:IsA("Model") then
local TargetHumanoidRootPart = Target.Parent:FindFirstChild("HumanoidRootPart")
if TargetHumanoidRootPart then
local TargetPosition = TargetHumanoidRootPart.Position
local Distance = (TargetPosition - Character.HumanoidRootPart.Position).Magnitude
if Distance < 10 then
print(`Target: {Target.Parent}`)
ReplicatedStorage.Remotes.Abilities:FireServer("Basic Telekinetic Push", Target.Parent)
LastAbilityTime = CurrentTime
else
warn(`Your current distance of {Distance} exceeds 10.`)
end
end
end
else
local RemainingCooldown = Cooldown - TimeSinceLastAbility
warn(`Cooldown Time: {RemainingCooldown}.`)
end
end
end)
Anonymous function bindings to UserInputService can last a long time if you don’t store the RBXScriptSignal reference to a variable and explicitly call Disconnect() on it. You’re probably creating a new binding to InputBegan every time you spawn a character, and you accumulate them over time. Depending on what happens to the instance this script is parented to, the binding may last for the length of your session, or it may eventually get garbage collected. Either way though, you should disconnect it yourself so that you don’t have to deal with this issue.
The RBXScriptSignal is the actual event, while the RBXScriptConnection is the connection made and returned when you call Event:Connect().
Here is an example of how you could use it:
--This script could be put in StarterCharacterScripts
local UIS = game:GetService("UserInputService")
local Character = script.Parent
local Humanoid = Character:WaitForChild("Humanoid")
local function Test(input)
--Do whatever you want to do here
end
--UIS.InputBegan would be the RBXScriptSignal, and the connection made from UIS.InputBegan:Connect() is the RBXScriptConnection
local Connection = UIS.InputBegan:Connect(Test)
Humanoid.Died:Wait()
Connection:Disconnect() --Disconnect the RBXScriptConnection (UIS.InputBegan:Connect) when the character dies
--This means Test() won't be called from UIS.InputBegan in this script after the character dies