Hello! I am trying to make a zipline for my game, but the character moves slower when it reaches a point.
Trying to lower the Dampening property and rise the Power property this happens:
Why does this happen and is there any way to fix it?
Hello! I am trying to make a zipline for my game, but the character moves slower when it reaches a point.
Trying to lower the Dampening property and rise the Power property this happens:
Why does this happen and is there any way to fix it?
The issue isn’t the BodyPosition, but the bezier curve itself
Since bezier curves don’t have equal distances between each bezier point, tighter curves are gonna have a slower speed since all those points in the curve are so close to each other
Ah, I see, is there any way to fix it though?
There’s a couple ways to do it for ex:
You can get the current bezier point and the next bezier point and get the distance
local distance = (currentPoint - nextPoint).Magnitude
And then after you can divide that distance by how fast you want to travel
local distance = (currentPoint - nextPoint).Magnitude
local speed = distance / 40
There’s also another way called arc length parameterization
but I won’t go into it since it’s a bit more complicated and involves a lot of math
I just realized I forgot the script! Here it is:
local speed = 0
local posPoints = {}
for i=1, #points do
if i > 1 then
speed += (points[i - 1].Position - points[i].Position).Magnitude * 1.3
end
table.insert(posPoints, points[i].Position)
end
if rope:FindFirstChild("Settings") then
if rope.Settings:FindFirstChild("ExtraSpeed") then
speed = speed / rope.Settings.ExtraSpeed.Value
end
end
coroutine.wrap(EnableCamera)()
local inc = (1 /(speed))
local this
local Distance
for t = 0, 1 - inc, inc do
local pos = Bezier.GetBezierPoint(t, unpack(posPoints))
local nextPos = Bezier.GetBezierPoint(t + inc, unpack(posPoints))
Distance = (pos - nextPos).magnitude
this = CFrame.lookAt(pos, nextPos, Vector3.new(0, 1, 0)) * CFrame.new(0, -2, Distance / -2)
bodyPos.Position = this.Position
bodyGy.CFrame = this * CFrame.new(0, -2, -Distance / 2)
part.CFrame = this
task.wait()
end
the local speed is part of it, just dont know why it looks like that
That’s some code but if I were you, I would put this inside a Heartbeat
loop
Here’s how I did mine:
bezier_test.rbxl (54.5 KB)
FYI, that isn’t the full script. I will send the full script tomorrow and I hope you reply.
Full scripts:
_zipline:
local plr = game.Players.LocalPlayer
local Bezier = require(game.ReplicatedStorage.GameScripts.Ziplines.Bezier)
local zipAnim = game.ReplicatedStorage.AnimationStorage.Swing
local travelling = false
local D = 0
function DisableSparkles()
local sparkles = plr.Character["Right Arm"].Sparkles
sparkles.Enabled = false
wait(4)
sparkles:Destroy()
end
function DisableBodyStuff()
local bodyPos = plr.Character.HumanoidRootPart.BodyPosition
local bodyGy = plr.Character.HumanoidRootPart.BodyGyro
wait(0.04)
bodyPos:Destroy()
bodyGy:Destroy()
for i, v in pairs(plr.Character:GetDescendants()) do
if v:IsA("Part") and v.Name ~= "HumanoidRootPart" then
v.CollisionGroup = "PlayerChars"
end
end
if game.ReplicatedStorage.ClientConfig.ZiplineCameraEnabled.Value then
workspace.CurrentCamera.CameraSubject = plr.Character.Humanoid
workspace.CurrentCamera.CameraType = Enum.CameraType.Custom
plr.CameraMaxZoomDistance = 400
plr.CameraMinZoomDistance = 0.5
end
end
function EnableCamera()
if game.ReplicatedStorage.ClientConfig.ZiplineCameraEnabled.Value then
plr.CameraMinZoomDistance = 10
plr.CameraMaxZoomDistance = 10
workspace.CurrentCamera.CameraSubject = plr.Character.Humanoid
workspace.CurrentCamera.CameraType = Enum.CameraType.Watch
end
end
function travelPoints(points, rope)
travelling = true
local humAnim = plr.Character.Humanoid:LoadAnimation(zipAnim)
local part = Instance.new("Part", plr.Character)
part.Anchored = true
part.CanCollide = false
part.Transparency = 1
local tag = Instance.new("IntValue", plr.Character)
tag.Name = "RidingZipline"
local sparkles = Instance.new("Sparkles", plr.Character["Right Arm"])
sparkles.SparkleColor = Color3.fromRGB(255, 179, 0)
local bodyPos = Instance.new("BodyPosition", plr.Character.HumanoidRootPart)
bodyPos.MaxForce = Vector3.new(math.huge, math.huge, math.huge)
bodyPos.P = 50000000
bodyPos.D = 0
local bodyGy = Instance.new("BodyGyro", plr.Character.HumanoidRootPart)
bodyGy.MaxTorque = Vector3.new(math.huge, math.huge, math.huge)
bodyGy.P = 50000
bodyGy.D = 50
humAnim:Play()
game.SoundService.ZiplineOn.TimePosition = 0.5
game.SoundService.ZiplineOn.Playing = true
game.SoundService.Zipline.Playing = true
local speed = 0
local posPoints = {}
for i=1, #points do
if i > 1 then
speed += (points[i - 1].Position - points[i].Position).Magnitude * 1.3
end
table.insert(posPoints, points[i].Position)
end
if rope:FindFirstChild("Settings") then
if rope.Settings:FindFirstChild("ExtraSpeed") then
speed = speed / rope.Settings.ExtraSpeed.Value
end
end
coroutine.wrap(EnableCamera)()
local inc = (1 /(speed))
local this
local Distance
for t = 0, 1 - inc, inc do
local pos = Bezier.GetBezierPoint(t, unpack(posPoints))
local nextPos = Bezier.GetBezierPoint(t + inc, unpack(posPoints))
Distance = (pos - nextPos).magnitude
this = CFrame.lookAt(pos, nextPos, Vector3.new(0, 1, 0)) * CFrame.new(0, -2, Distance / -2)
bodyPos.Position = this.Position
bodyGy.CFrame = this * CFrame.new(0, -2, -Distance / 2)
part.CFrame = this
task.wait()
end
bodyPos.Position = this.Position
bodyGy.CFrame = this * CFrame.new(0, -2, -Distance / 2)
coroutine.wrap(DisableBodyStuff)()
part:Destroy()
tag:Destroy()
coroutine.wrap(DisableSparkles)()
game.SoundService.Zipline.Playing = false
game.SoundService.ZiplineOff.TimePosition = 0.5
game.SoundService.ZiplineOff.Playing = true
humAnim:Stop()
travelling = false
end
function sort(tab)
local finished = {}
for i=1, #tab do
for x=1, #tab do
if tonumber(string.sub(tab[x].Name, 6, #tab[x].Name)) == i then
finished[i] = tab[x]
end
end
end
return finished
end
for _,i in ipairs(plr.Character:GetChildren()) do
if i:IsA("BasePart") then
i.Touched:Connect(function(p)
if p.Name == "StartPoint" and p.Parent.Name == "_Rope" and not travelling then
local points = {}
for _,x in ipairs(p.Parent:GetChildren()) do
if string.find(x.Name, "Point") then
table.insert(points, x)
end
end
for i, v in pairs(plr.Character:GetDescendants()) do
if v:IsA("Part") and v.Name ~= "HumanoidRootPart" then
v.CanCollide = false
v.CollisionGroup = "Zipline"
end
end
points = sort(points)
travelPoints(points, p.Parent)
end
end)
end
end
Bezier:
local module = {}
function Lerp(P0, P1, T)
return (1 - T) * P0 + T * P1
end
function module.GetBezierPoint(T, ...)
local Points = {...}
while (#Points > 1) do
for i = 1, #Points - 1 do
Points[i] = Lerp(Points[i], Points[i + 1], T)
end
Points[#Points] = nil
end
return Points[1]
end
function createPart(Point, NextPoint, Parent)
local ZiplinePart = Instance.new("Part")
ZiplinePart.Anchored = true
ZiplinePart.Size = Vector3.new(0.25, 0.25, (Point - NextPoint).Magnitude)
ZiplinePart.CFrame = CFrame.lookAt(Point, NextPoint, Vector3.new(0, 1, 0)) * CFrame.new(0, 0, ZiplinePart.Size.Z / -2)
ZiplinePart.Material = "Fabric"
ZiplinePart.Color = Color3.new(0, 0, 0)
ZiplinePart.Parent = Parent
ZiplinePart.CanCollide = false
return ZiplinePart
end
function module.new(par, ...)
local points = {...}
local posPoints = {}
local speed = 0
for i=1, #points do
table.insert(posPoints, points[i].Position)
if i > 1 then
speed += (points[i - 1].Position - points[i].Position).Magnitude * 1.3
end
end
local inc = (1 / 40)
for i = 0, 1.0025 - inc, inc do
local Point = module.GetBezierPoint(i, unpack(posPoints))
local NextPoint = module.GetBezierPoint(i + inc, unpack(posPoints))
createPart(Point, NextPoint, par)
end
end
return module
I tried switching to this one and it works so much better! Thank you so much for helping me!
This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.