There is a problem with the roads. They must accelerate the character, and when he gets off the road she will make him the usual speed (16
). Should work with characters like R15
. That is the problem. For some reason, nothing strange happens with characters like R6, and with characters like R15
- when moving along the road, their speed drops to 16
, and rises to 60
so every second. As a result, the character moves in jerks. Below I will show the only more or less working way that I have obtained.
First script
local part = script.Parent local function onTouch(part) local parent = part.Parent if game.Players:GetPlayerFromCharacter(parent) then parent.Humanoid.WalkSpeed = 60 end end part.Touched:Connect(onTouch)
Second script
local part = script.Parent local function onTouchEnded(part) local parent = part.Parent if game.Players:GetPlayerFromCharacter(parent) then parent.Humanoid.WalkSpeed = 16 end end part.TouchEnded:Connect(onTouchEnded)
If you are not busy, please improve these scripts, or at least reduce jerks. Thanks in advance.
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.