Speed Lock Part turns off and on

Hello! So I have this script on a part that locks your speed at 50 but once you step off of it it unlocks you speed. But there is a problem. It constantly turns off and on for some reason. And I am not sure what the cause is and how to fix it. Does anyone know?

Code:

local spawnLocation = script.Parent

spawnLocation.TouchEnded:Connect(function(basePart: BasePart)
    if basePart.Parent then
         local humanoid = basePart.Parent:FindFirstChildWhichIsA("Humanoid")

         if not humanoid then
             return
         end

         humanoid.WalkSpeed = 50
    end
end) 
1 Like

I could be wrong when saying this, but I’m pretty certain Touched and TouchEnded are not very reliable and I usually stay away from using them (this doesn’t apply in all cases).

For this type of thing, I suggest using raycasting.


I’m not too sure how familiar you are with scripting, but I tried explaining the code below. I really suggest you take the time to try to understand it instead of just copy & pasting it

This should go in a localscript under StarterPlayerScripts:

local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local CollectionService = game:GetService("CollectionService")

local Player = Players.LocalPlayer
local Character = nil
local HumanoidRootPart = nil
local Humanoid = nil

local SpeedChangerTag = "SpeedChanger"
local DefaultSpeed = 16 -- WalkSpeed when not on a speed changer
local DownwardsDirection = Vector3.new(0, -10, 0)
local DownwardsRaycastParams = RaycastParams.new()

DownwardsRaycastParams.FilterType = Enum.RaycastFilterType.Blacklist
DownwardsRaycastParams.FilterDescendantsInstances = {}

------------

local function Heartbeat()
	if HumanoidRootPart and Humanoid and Humanoid.Health > 0 then -- If our character is alive
		
		local RaycastResult = workspace:Raycast(HumanoidRootPart.Position, DownwardsDirection, DownwardsRaycastParams) -- Cast a ray below us
		local Hit = RaycastResult and RaycastResult.Instance
		
		if Hit and CollectionService:HasTag( Hit, SpeedChangerTag ) then -- If the raycast hit something and it has the SpeedChanger tag
			
			-- Change humanoid speed to the hits "Speed" attribute or otherwise 25
			Humanoid.WalkSpeed = Hit:GetAttribute("Speed") or 25
		else
			
			-- The raycast didnt hit a speed changer, so change our speed to the default speed
			Humanoid.WalkSpeed = DefaultSpeed
		end
		
	end
end

local function CharacterAdded(NewCharacter)
	
	-- Update variables for my character
	Character = NewCharacter
	HumanoidRootPart = Character:WaitForChild("HumanoidRootPart")
	Humanoid = Character:WaitForChild("Humanoid")
	
	-- Change params so the new character is blacklisted
	DownwardsRaycastParams.FilterDescendantsInstances = {Character}
end


CharacterAdded(Player.Character or Player.CharacterAdded:Wait())
-- Attach our Heartbeat function to RunService.Heartbeat
RunService.Heartbeat:Connect(Heartbeat)
-- Attach our CharacterAdded function to Player.CharacterAdded
Player.CharacterAdded:Connect(CharacterAdded)

So we have the part which checks if we’re on a speed changer, now we have to actually set the parts that are a speed changer. Here is an example of applying the tag and attribute to a part:

local CollectionService = game:GetService("CollectionService")

local SpeedChangerTag = "SpeedChanger"
local ThePart = workspace:WaitForChild("SpeedPart") -- This should be your part

CollectionService:AddTag(ThePart, SpeedChangerTag) -- Add the SpeedChanger tag to the part
ThePart:AddAttribute("Speed", 50) -- Add an attribute to the part called "Speed", and set its value to 50

Now when you stand on the part, the system will detect it, get its Speed attribute and change your speed to it.


The good thing about this system is you can have multiple parts which set your speed while on, you can use the second code example and apply it to as many parts as you’d like.

This is a lot to read and understand, let me know if you have any questions

1 Like

They are reliable, they just arent very consistent.

1 Like