Basic Question: How do I make a tool that increases walkspeed up to some time even after it isn't in the inventory anymore

Hi, I am trying to get into scripting, and as a start I want to make a ball which will go into different players inventory upon touching the ball.

So right now I have a ball that goes into someones backpack when touched whilst in someone else’s hand. Very basic.

However I would now like to give people with the ball a walkspeed increase up to 5 seconds after they lost the ball to someone else. I’ve tried doing this with a script inside the ball, but since people actually lose the ball they just stay at the walkspeed boost the ball has.
I am thinking of doing something with a script in serverstorage using a while loop to check all players without a ball in their inventory and reset their walkspeed. But I cannot find any tutorials on this. Tutorial suggestions or some more background information would be appreciated.

I am sorry if my explanation isn’t that good, I am just very very new to this.
Thanks in Advance!

I’ve tried the following code:


But since the ball is not actually unequipped but lost this didn’t work either :stuck_out_tongue:

2 Likes

image
The parent of the tool is the backpack instance, not the player’s name so the player is now equal to “Backpack”, and the script won’t be able to run. You need to change it to:
tool.Parent.Parent.Name.

2 Likes

Thanks, I tried this but if I change it to tool.Parent.Parent.Name It doesn’t even give me the walkspeed upgrade. with tool.Parent.Name it does, so weirdly it only makes it worse??
But you’re right the tool is inside backpack so now I don’t even know why it works this way and not your way xd

It is because when the tool is equipped it transfers from the player’s backpack to the character.
As you unequip it, the tool again transfer’s to the player’s backpack

1 Like

Yes I am aware of that, atleast of the code that I added in the picture above. But I am wondering now how can I actually give the person with the ball 5 seconds extra walkspeed even after the ball is lost.
So in other words how should I make a script that constantly checks if the player has the ball or not, if not reset walkspeed to 16 again. :slight_smile:

you can try delay

local timeDelay = 1 -- how many seconds will have to pass until you change the walkspeed back
delay(timeDelay, function()
player.Character.Humanoid.WalkSpeed = 16
end)

and you should also remove the unequipped event listener because it will change the walkspeed back when the ball is lost which is what you don’t want.

1 Like

A rough solution would be to use FindFirstChild to get the character from the workspace, then move from there. However, if you’re looking towards using the Players service then you might want to add a global type variable to get the player, change it from your equipped function, then you won’t have to worry about the variable on your unequipped function.

1 Like

I put the code right here


However in this case I don’t get any delayed walkspeed boost even when unequipping.
Indeed the unequipped event listener is irrelevant in my code that’s true. But I don’t know if this delay would actually work since after passing the ball to someone else also the script inside the ball will be passed to someone else so the original ‘ball owner’ wouldn’t get anything changed

Yeah I would like to use FindFirstChild too, but there are a few obstacles I don’t know how to solve in that case.
If I use FindFirstChild, I am searching the player based on the tool (the ball), which I want,
However I cannot put the script inside the ball itself, since the script would be lost from that player when someone steals the ball. So instead I need something to search for the player with the tool, but I don’t know how to reference the tool in a script not inside the tool without knowing which player has it.

A tool when equipped goes into the player’s model in workspace, (same applies for NPCs). Not sure if this information is needed or not, but from there I’d point out that you can do a script.Parent.Parent type thing on equipped so you have a reference to the Player.Name
The script would go into the tool itself, not into the handle. (although I suppose you could make it work in the handle)

1 Like

Yeah but I have another script in the tool which moves the tool to someone else upon touch, so If I would put it into handle the script would somehow have to remember in which player’s backpack it was last to still execute the extra 5 seconds of speed boost. So I don’t really see how it could work if I do place it in the tool itself.

it should work, try commenting out the unequipped part

you can comment out large code code blocks with --[[ and finish with ]]

so it would look like this

--[[
tool.Unequipped:Connect(function()
-- all of the code here
end)
]]
1 Like

At that point you can add a local variable for the Unequipped function which takes the variable from your Equipped function. This variable will host the player (or player.name) locally for that function.
On the same hand however, why not use tool.Activated instead?

1 Like

Okay, wait let me rephrase, I see alot of people not being on the same line with me.
So I have a tool which I know uploaded here: Ball test - Roblox which you can test in a 2-player server. The tool ‘moves itself’ into another players inventory upon touching the player with the handle afterwhich the ball is untransferrable for 5 seconds. I am not really interested in the Unequipped function as the tool is ment to be transferred when being equipped making the unequipped function useless. I want the player to gain walkspeed when holding the ball and for 5 more seconds after the ball is transferred, but you can try, If you do this with a script inside the ball I don’t think it’ll work since the whole tool gets transferred to another player before the code could execute for the original player

You could possibly use a .Changed event then, however I personally haven’t used this event for a really long time.

There’s a better version of .Changed in this event considering you are changing the tool’s parent.
GetPropertyChangedSignal
I haven’t used this, but it seems promising.

1 Like

alright i think i understand you now!

you basically want to give the player currently holding the ball a speed of 30
and whenever he gets that ball taken away you want to give him 5 seconds of that speed and then set it to default right?

well there is a key issue here, you’re changing the parent of the tool so it doesn’t affect the player that we intended to affect

to fix this we need a third party with the use of a bindable event

so first things first go to replicated storage and press right click and press “Insert Object”
and search for “BindableEvent”

call it “DelayWalkspeed” because that’s how i named it, if you want to change it you’re going to have to change it in all the scripts that i will show later on

and now we want to create a script that will react to the bindable event so go to ServerScriptService, right click and insert a script

you can name it whatever you want, it doesn’t matter!

so in your script called… Script we don’t want the unequipped event listener because we don’t want to set the walkspeed as soon as it’s unequipped, so we remove it

that’s how it should look like:

local tool = script.Parent
local speed = 30

tool.Equipped:Connect(function()
	local player = game.Players:FindFirstChild(tool.Parent.Name)
	if player then
		player.Character.Humanoid.WalkSpeed = speed
	end
end)

and now moving on to the Giveaway script

we want to detect if a player has touched the ball if he did then set the parent to the player
and when we do that we also involve the third party who will handle the walkspeed

how do we involve the third party? bindable events can be fired and used to receive data. we specifically used a bindable event because the communication is from server to server.

so the giveaway script should look like something like this:

local tool = script.Parent					--Tool variable
local debounce = true

local delayWalkspeed = game:GetService("ReplicatedStorage"):WaitForChild("DelayWalkspeed") -- get the bindable event

tool.Handle.Touched:Connect(function(Hand)
	if Hand.Parent:FindFirstChild("Humanoid") and debounce then 
		debounce = false
				
		local humanoid = tool.Parent:FindFirstChild("Humanoid") -- check if it's a player by checking if it has a humanoid
		
		if humanoid then
			tool.Parent = Hand.Parent
			delayWalkspeed:Fire(humanoid.Parent) -- pass the character object as a parameter
		end
		
		wait(5)
		debounce = true
	end
end)

now to the final part we go to the script we created before in ServerScriptService and we want to receive the character we passed as a parameter and reset its walkspeed after 5 seconds

so how do we do that?

simply with the .Event listener

your code should look like this:

local delayWalkspeed = game:GetService("ReplicatedStorage"):WaitForChild("DelayWalkspeed") -- get the bindable event

local delayTime = 5

delayWalkspeed.Event:Connect(function(character) -- get the character object that's been passed
	delay(delayTime, function()
		character.Humanoid.WalkSpeed = 16
	end)
end)

i will leave you the project file in case you want to experiment with it more. ball.rbxl (30.1 KB)

have fun coding!

5 Likes

aight, thank you :slight_smile: I’ll look into that specific event.

Yeah, use the GetPropertyChangedSignal to (hopefully) detect when the tool moves, and delay a function to reset that player’s speed after their 5 seconds are up.

Wow, 10/10 for the explantion. Very Informative, and also thank you very much to fixing it already too. As a newbie to scripting it’s very hard to find which methods to use sometimes, but this information will probably help me with other scripts too! You’re very helpful, thanks! :slight_smile:

2 Likes