Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

Why do callbacks of ContextActionService:BindAction stop working after death?

I created a simple ShiftToRun LocalScript (pasted below).

It works fine, but after death + respawn it stops working, if I put it in: StarterPlayerScripts, or ReplicatedFirst.

However, it keeps working after death, if I put it in StarterGui.

I have a few questions (if I may?):

  1. I could not find any concrete info on this, but it appears that the LocalScript is destroyed (and thus the callback is removed from ContextActionService) on death for some reason. Is that about right?
  2. More importantly, is there a clear guideline on how to persist LocalScripts after death? Is StarterGui the only way to persist for a script after death?
  3. And, in general, when to put what kind of script where? What are the pros and cons of all the different locations? Is there any general guideline or a tabular overview somewhere?
  4. What about general overview over script lifecycles? When and how long do they live? What happens when they get destroyed?
local player = game.Players.LocalPlayer
local cas = game:GetService("ContextActionService")

local runSpeed = script.RunSpeed.Value

local isRunning = false
local char = player.Character or player.CharacterAdded:wait()
local humanoid = char:WaitForChild('Humanoid')
local walkSpeed = humanoid.WalkSpeed

local toggleRun = function(actionName, actionInputState, actionInputObject)
	--if actionInputState == Enum.UserInputState.Begin then
	isRunning = not isRunning
	if isRunning then
		humanoid.WalkSpeed = runSpeed
	else
		humanoid.WalkSpeed = walkSpeed
	end
	--end
end
 
cas:BindAction("toggleRun", toggleRun, true, Enum.KeyCode.LeftShift)

1 comment

0

You can put it in StarterPlayerScripts.

1 answer

✓ Accepted answer

The script will persist on death as long as it is not parented to something that is destroyed on death, such as Backpack or Character.

Putting it into the StarterGui doesn't make it persist on death but rather reruns the same script each time you respawn.

Now, why doesn't your script work? The answer is simple: you are caching the Humanoid.

Each time the player respawns, they have a different char and different humanoid. And in your script, you define the humanoid variable as the current humanoid and don't update it on respawn.

So what you should do, is declare the humanoid inside the callback instead.

local player = game.Players.LocalPlayer
local cas = game:GetService("ContextActionService")

local runSpeed = script.RunSpeed.Value

local isRunning = false

local toggleRun = function(actionName, actionInputState, actionInputObject)
    local humanoid = player.Character and player.Character:WaitForChild("Humanoid") or player.CharacterAdded:Wait():WaitForChild("Humanoid")
    --if actionInputState == Enum.UserInputState.Begin then
    isRunning = not isRunning
    if isRunning then
        humanoid.WalkSpeed = runSpeed
    else
        humanoid.WalkSpeed = walkSpeed
    end
    --end
end

cas:BindAction("toggleRun", toggleRun, true, Enum.KeyCode.LeftShift)

3 comments

0

that explains it! thanks a bundle! - I'm also thinking that instead of waiting, to just ignore the call while there is no character or humanoid present to prevent queued up key events to result in a big mess...

0

Considering how it will be re-run every time I respawn, wouldn't it add more and more event handlers every time, I die?

1

If you put it into StarterGui - yes it will. That's why you should make it only run once

This discussion is preserved as it was. New answers, comments, and votes are closed.