I making an ability for a game and anytime I use the UserInputservice it works the first time but when I reset my character it just stops working. What do I need to do so this does not happen again. Any Fixes this is my second time posting this?
Your code could be the issue. I feel that if this was a bug, big developers (that have #bug-reports acess) would post about it
Can you check my code
local UIS = game:GetService("UserInputService")
local module = {}
local db = false
local ShockClone
local WeldConst
function module:Activate(Plr:Player)
local Char = Plr.Character or Plr.CharacterAdded:Wait()
local Keycode = Enum.KeyCode.E
local Animation = game.ReplicatedStorage.Abilities["Ice Barrage"]
local Humanoid = Char:FindFirstChildOfClass("Humanoid")
local Animator = Humanoid:FindFirstChildOfClass("Animator")
local Track = Animator:LoadAnimation(Animation)
local ShockNormalSize = Vector3.new(5.989, 0.592, 6.125)
local TweenService = game:GetService("TweenService")
local Goals = TweenInfo.new(
0.1,
Enum.EasingStyle.Linear,
Enum.EasingDirection.In
)
UIS.InputBegan:Connect(function(inp,gpe)
if gpe then return end
if inp.KeyCode == Enum.KeyCode.E and not db then
print(Keycode)
db = true
Track:Play()
Track:GetMarkerReachedSignal("Blast"):Once(function()
ShockClone = game.ReplicatedStorage.Shock:Clone()
WeldConst = Instance.new("Weld")
ShockClone.Parent = workspace
local ShockTween = TweenService:Create(ShockClone,Goals,{["Size"] = ShockNormalSize})
local ShockTween2 = TweenService:Create(ShockClone,Goals,{["Transparency"] = 1})
WeldConst.Parent = Char:WaitForChild("Right Arm")
WeldConst.Part0 = Char:WaitForChild("Right Arm")
WeldConst.Part1 = ShockClone
ShockClone.Anchored = false
ShockClone.CanCollide = false
ShockClone.Size = Vector3.new(1,1,1)
ShockClone.Position = Char:FindFirstChild("Right Arm").Position + Vector3.new(0,1,0)
ShockTween2:Play()
ShockTween:Play()
end)
Track.Ended:Connect(function()
task.wait(1)
db = false
end)
Humanoid.Died:Connect(function()
Track:Stop()
WeldConst:Destroy()
ShockClone:Destroy()
db = false
end)
Track.Stopped:Connect(function()
print("Sup")
end)
end
end)
end
return module
When and where are you calling your Activate
function?
In this local script I had my first piece of code in a module script than I accessed it here
local plr = game.Players.LocalPlayer
local Char = plr.Character or plr.CharacterAdded:Wait()
local Hum = Char:FindFirstChild("Humanoid") or Char:WaitForChild("Humanoid")
local IceDaggerModule = require(script.Ice_Barrage_Framework)
IceDaggerModule:Activate(plr)
Okay I don’t really see anything wrong. How about you try to add a print statement above the part where you check if the player is typing
I just saw that Enum.KeyCode.E
was outputted after you respawned. So what’s going on?
There is a variable named keycode and I used that variable in this line
if inp.KeyCode == Enum.KeyCode.E and not db then
but I forgot to delete this variable so when I press e it just prints Enum.keycode.E
Oh I see. But you said that UIS didn’t work altogether? But here it seems like it’s working fine
Yeah I just don’t know why every time I reset during the move it just does not play the animation again
I cant really find anything that could not make the animation run.
Uhh maybe in the Died
event listener make remove the Track:Stop()
line? Idk
Would I need to use contextactionservice
Sure if you want I guess since you can just bind an action and that’s be better. But userInputService isnt the reason your code ain’t working but you could try if you want
I took a look at the code, not completely sure what the issue is, but I might have an idea.
What I’d like you to do is:
In the modulescript, add a couple lines with asserts to break the script if something doesn’t exist, mainly the variables Char, Humanoid and Animator. Those might not exist and therefore stop the animation as a result.
Your modulescript should look something like this with the change I suggested.
local UIS = game:GetService("UserInputService")
local module = {}
local db = false
local ShockClone
local WeldConst
function module:Activate(Plr:Player)
local Char = Plr.Character or Plr.CharacterAdded:Wait()
assert(Char, "Could not find Character!")
local Keycode = Enum.KeyCode.E
local Animation = game.ReplicatedStorage.Abilities["Ice Barrage"]
local Humanoid = Char:FindFirstChildOfClass("Humanoid")
local Animator = Humanoid:FindFirstChildOfClass("Animator")
assert(Humanoid, "Could not find Humanoid!")
assert(Animator, "Could not find Animator!")
local Track = Animator:LoadAnimation(Animation)
local ShockNormalSize = Vector3.new(5.989, 0.592, 6.125)
local TweenService = game:GetService("TweenService")
local Goals = TweenInfo.new(
0.1,
Enum.EasingStyle.Linear,
Enum.EasingDirection.In
)
UIS.InputBegan:Connect(function(inp,gpe)
if gpe then return end
if inp.KeyCode == Enum.KeyCode.E and not db then
print(Keycode)
db = true
Track:Play()
Track:GetMarkerReachedSignal("Blast"):Once(function()
ShockClone = game.ReplicatedStorage.Shock:Clone()
WeldConst = Instance.new("Weld")
ShockClone.Parent = workspace
local ShockTween = TweenService:Create(ShockClone,Goals,{["Size"] = ShockNormalSize})
local ShockTween2 = TweenService:Create(ShockClone,Goals,{["Transparency"] = 1})
WeldConst.Parent = Char:WaitForChild("Right Arm")
WeldConst.Part0 = Char:WaitForChild("Right Arm")
WeldConst.Part1 = ShockClone
ShockClone.Anchored = false
ShockClone.CanCollide = false
ShockClone.Size = Vector3.new(1,1,1)
ShockClone.Position = Char:FindFirstChild("Right Arm").Position + Vector3.new(0,1,0)
ShockTween2:Play()
ShockTween:Play()
end)
Track.Ended:Connect(function()
task.wait(1)
db = false
end)
Humanoid.Died:Connect(function()
Track:Stop()
WeldConst:Destroy()
ShockClone:Destroy()
db = false
end)
Track.Stopped:Connect(function()
print("Sup")
end)
end
end)
end
return module
What do you mean asserts are those like breakpoints and if so, what lines should I put these
This is most likely a script lifetime issue. If you run your code from a LocalScript in StarterPlayerScripts, it waits for your character to spawn, and holds onto a reference to that character for the life of the script, which is probably the whole session.
For things to work through respawns, you need to connect to the Player.CharacterAdded event so that you can either update the references your module script holds, or destroy the instance entirely and make a new one for each character spawn.
This makes a lot of sense but I just need to figure out where I need to put this event
You’re calling :Activate()
once. At that time, it stores your current character in a variable.
But after you reset, that character gets removed, so future usages of that Char
variable (or any variables referencing things inside it e.g. Humanoid
, Animator
) are pointing to a removed character.
You need to update your variables to point to a new character on spawn, and re-do any connections on outdated objects (like humanoid.Died
)
So you probably should be structuring your code something like this:
--!strict
local UserInputService = game:GetService("UserInputService")
local TweenService = game:GetService("TweenService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Workspace = game:GetService("Workspace")
local KEY_CODE = Enum.KeyCode.E
local SHOCK_OFFSET = Vector3.yAxis * 1
local SHOCK_LIFETIME = 0.1
local SHOCK_TWEEN_INFO = TweenInfo.new(SHOCK_LIFETIME, Enum.EasingStyle.Linear, Enum.EasingDirection.In)
local DEBOUNCE_SECONDS = 1
local SHOCK_END_GOALS = {
Size = Vector3.new(5.989, 0.592, 6.125),
Transparency = 1,
}
local SHOCK_BEGIN_SIZE = Vector3.one
local animation: Animation = ReplicatedStorage.Abilities["Ice Barrage"]
local shockPrefab: BasePart = ReplicatedStorage.Shock
local module = {}
function module._animateShock(shock: BasePart, spawnAtPart: BasePart)
local weld = Instance.new("Weld")
local shockTween = TweenService:Create(shock, SHOCK_TWEEN_INFO, SHOCK_END_GOALS)
weld.Part0 = spawnAtPart
weld.Part1 = shock
weld.Parent = spawnAtPart
shock.Anchored = false
shock.CanCollide = false
shock.Size = SHOCK_BEGIN_SIZE
shock.Position = spawnAtPart.Position + SHOCK_OFFSET
shock.Parent = Workspace
shockTween:Play()
shockTween.Completed:Once(function()
shock:Destroy()
end)
end
function module._canShock(inputObject: InputObject, isProcessed: boolean, debounce: boolean): boolean
if isProcessed then
return false
end
if debounce then
return false
end
if inputObject.UserInputType ~= Enum.UserInputType.Keyboard then
return false
end
if inputObject.KeyCode ~= KEY_CODE then
return false
end
return true
end
function module._onCharacterAddedAsync(character: Model)
local rightArm = character:WaitForChild("Right Arm") :: BasePart
local humanoid = character:WaitForChild("Humanoid") :: Humanoid
local animator = humanoid:WaitForChild("Animator") :: Animator
local track: AnimationTrack = animator:LoadAnimation(animation)
local debounce = false
local inputConnection = UserInputService.InputBegan:Connect(function(inputObject: InputObject, isProcessed: boolean)
if not module._canShock(inputObject, isProcessed, debounce) then
return
end
debounce = true
local newShock = shockPrefab:Clone()
track:GetMarkerReachedSignal("Blast"):Once(function()
module._animateShock(newShock, rightArm)
end)
local diedConnection = humanoid.Died:Once(function()
newShock:Destroy()
end)
track.Ended:Once(function()
diedConnection:Disconnect()
task.wait(DEBOUNCE_SECONDS)
debounce = false
end)
track:Play()
end)
humanoid.Died:Once(function()
track:Stop()
track:Destroy()
inputConnection:Disconnect()
end)
end
function module.activate(player: Player)
if player.Character then
task.spawn(module._onCharacterAddedAsync, player.Character)
end
player.CharacterAdded:Connect(module._onCharacterAddedAsync)
end
return module
Assert is an error, but it only occurs if the variable given in the first argument is invalid. If it is, it will print out whatever string you put as the second argument.
I’m asking you to put assert in front of variables that might change, like the Char, Humanoid, and Animator variables. Since a player’s character gets destroyed once they respawn, the old character that the Char variable points to would no longer exist once you reuse the function, if I understand the function correctly.
(also I know this response is late, but I just logged into the dev forum)
Documentation example of assert
local product = 90 * 4
assert(product == 360, "Oh dear, multiplication is broken")
-- The line above does nothing, because 90 times 4 is 360