It's because of R15 animations. Animations control the position of your character's feet, and whenever their feet stop touching the part, the TouchEnded event fires.
The solution I wrote is a little bit complicated, but it works.
I'd put all of this in a single script(you don't necessarily need to put the two different event listeners into two different scripts):
local part = game.Workspace:WaitForChild("Part")
local minX = part.Position.X - part.Size.X/2
local maxX = part.Position.X + part.Size.X/2
local minZ = part.Position.Z - part.Size.Z/2
local maxZ = part.Position.Z + part.Size.Z/2
local positionOne = Vector3.new(minX, part.Position.Y + part.Size.Y/2, minZ)
local positionTwo = Vector3.new(maxX, (part.Position.Y + part.Size.Y/2) + 4, maxZ)
local region = Region3.new(positionOne, positionTwo)
while true do
wait()
local parts = game.Workspace:FindPartsInRegion3(region, nil, 1000)
for index, player in pairs(game.Players:GetPlayers()) do
local chr = player.Character or player.CharacterAdded:Wait()
local humanoid = chr:WaitForChild("Humanoid")
local found = false
for i, v in pairs(parts) do
if v.Parent == chr then
found = true
end
end
if found then
humanoid.WalkSpeed = 60
else
humanoid.WalkSpeed = 16
end
end
end
To explain, we reference the part that we're using as the road.
The next few lines may be a little bit confusing, but bear with me.
So, to combat the issue of the character's WalkSpeed being changed rapidly, I've decided to go with using a value that's called Region3.
Region3 allows you to define a 3D region in which parts can be searched for.
To create one, it takes two arguments, both of which are Vector3(positional) values.
The region ranges from the lowest X and Z values to the highest X and Z values of the part's surface area. It also ranges from the Y position at the surface of the part(I don't know how tall your part is) to 4 studs above it, giving plenty of headroom for players to walk in.
The variable "positionOne" is the lowest X, Y, and Z coordinates, and the variable "positionTwo" is the highest X, Y, and Z coordinates.
We use a while loop to constantly look for all of the parts inside of that region we created. We go through all of the players in the game. If their character contains a part that was found in the region, then set their WalkSpeed to 60. Otherwise, set it to 16.
I tested this and it works. Tell me if you run into any issues.
EDIT: After messing around a little bit more in Studio with this code, I realized that the server is sometimes a little bit slow to change your WalkSpeed upon entering or exiting the region. This can be fixed by inserting a LocalScript into StarterGui and changing the code a little bit:
local plr = game:GetService("Players").LocalPlayer
local chr = plr.Character or plr.CharacterAdded:Wait()
local humanoid = chr:WaitForChild("Humanoid")
local part = game.Workspace:WaitForChild("Part")
local minX = part.Position.X - part.Size.X/2
local maxX = part.Position.X + part.Size.X/2
local minZ = part.Position.Z - part.Size.Z/2
local maxZ = part.Position.Z + part.Size.Z/2
local positionOne = Vector3.new(minX, part.Position.Y + part.Size.Y/2, minZ)
local positionTwo = Vector3.new(maxX, (part.Position.Y + part.Size.Y/2) + 4, maxZ)
local region = Region3.new(positionOne, positionTwo)
game:GetService("RunService").RenderStepped:Connect(function()
local parts = game.Workspace:FindPartsInRegion3(region, nil, 1000)
local found = false
for i, v in pairs(parts) do
if v.Parent == chr then
found = true
end
end
if found then
humanoid.WalkSpeed = 60
else
humanoid.WalkSpeed = 16
end
end)
Since you can modify your own Humanoid's WalkSpeed on the client(and not others' Humanoids), this would work just the same, but faster.
There's 3 reasons it's faster.
Instead of using a while loop, we're using an event listener for the RenderStepped event of RunService. The event fires 60 times a second, as opposed to a measly 30 times a second with the server. It's checking and modifying your humanoid's WalkSpeed 60 times a second, as opposed to 30 times a second.
It's done on the client side, so it's not as performance-intensive as doing it with the server is. The server shouldn't be as laggy as it would be if you did it with the server.
The client gets the most accurate position of their character before the server does, so it knows instantly whether or not the character is in the region.
5 comments
this man is a genius
True
Sorry for the long wait, this works. Is it possible to make all the objects in the Roads folder highlighted? Otherwise, only one of all roads accelerates.
Is it possible to make all the objects in the Roads folder highlighted?
Do you mean if you're standing above any road part inside of the roads folder, you start running? Just iterate through the folder and run the above code(nested in a spawn function) for each iteration and it should work.