So in Find Everything by Polyhex, there’s some tightropes parts that the player can walk onto back and forth, and i was trying to make something similair, but i cant manage to make the bouncy effect when you land or jump off the rope (i tried using TweenService, but the player is only able to walk after the tween has ended), so i have to use lerping with a spring module to achieve what i want, the problem is that… i don’t know how to do that
here’s the code (without any effects):
----- Services -----
--
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local UserInputService = game:GetService("UserInputService")
local TweenService = game:GetService("TweenService")
local RunService = game:GetService("RunService")
----- Modules -----
--
----- Variables -----
--
local Player = game.Players.LocalPlayer
local Character = Player.Character
if Character == nil then Player.CharacterAdded:Wait() end
local Humanoid = Character:WaitForChild("Humanoid")
local RootPart = Character:WaitForChild("HumanoidRootPart")
local Camera = game.Workspace.CurrentCamera
local PlayerModule = require(Player:WaitForChild("PlayerScripts"):WaitForChild("PlayerModule"))
local Controls = PlayerModule:GetControls()
Humanoid:SetStateEnabled(Enum.HumanoidStateType.Climbing,false)
local BaseWalkSpeed = 16
----- Rope Variables -----
--
local Ropes = game.Workspace:WaitForChild("Tight Ropes")
local RopeOnUse = false
local RopeOnCooldown = false
local LastRopeAttachment = nil
local AnimEvent = nil
local AnimEventRun = nil
local AnimEventIdle = nil
local AnimEventArms = nil
local RunForce = nil
local ForceAttachment = nil
local ForceObject = nil
local RopeJumpHeight = 18
local function CharacterGetInputDirection()
local MovementVector = Controls:GetMoveVector()
local CameraDirection = Camera.CFrame.LookVector
local NonRoundedOffset = CFrame.lookAt(Vector3.new(0, 0, 0), Vector3.new(CameraDirection.X, 0, CameraDirection.Z)) * MovementVector
local Offset = Vector3.new(math.round(NonRoundedOffset.X), NonRoundedOffset.Y, math.round(NonRoundedOffset.Z))
return if (Offset.Magnitude > 0) then Offset.Unit else Vector3.new(0, 0, 0) --Prevents NaN
end
local function SetForce(RopeAttachment)
if RopeAttachment then --Create
if ForceAttachment then ForceAttachment:Destroy() end
--Attachment
ForceAttachment = Instance.new("Attachment")
ForceAttachment.Name = "RopeForceAttachment"
ForceAttachment.Parent = RootPart
--Force
ForceObject = Instance.new("AlignPosition")
ForceObject.Mode = Enum.PositionAlignmentMode.OneAttachment
ForceObject.RigidityEnabled = true
ForceObject.ApplyAtCenterOfMass = true
ForceObject.MaxForce = math.huge
ForceObject.Attachment0 = ForceAttachment
ForceObject.Parent = ForceAttachment
else --Destroy
if ForceAttachment then ForceAttachment:Destroy() end
end
end
local function TriggerRope(RopePart)
if RopePart and not RopeOnUse and not RopeOnCooldown then --Trigger on
RopeOnUse = true
RopeOnCooldown = true
Humanoid.WalkSpeed = 24
--Get force
local RopeAttachment = RopePart:WaitForChild("MiddleAttachment")
local RopeBackAttachment = RopePart:WaitForChild("BackwardsAttachment")
local RopeFrontAttachment = RopePart:WaitForChild("ForwardAttachment")
LastRopeAttachment = RopeAttachment
SetForce(RopeAttachment)
--Get bounding box
local Orientation, Size = Character:GetBoundingBox()
--Position rope below player when they touch the rope
RopeAttachment.WorldPosition = Vector3.new(ForceAttachment.WorldPosition.X, RopeAttachment.WorldPosition.Y - 1.75, ForceAttachment.WorldPosition.Z)
RopeAttachment.Position = Vector3.new(RopeAttachment.Position.X, -1.75, 0)
--Apply it
local LastSpeed = nil
local LastPos = nil
if RunForce then RunForce:Disconnect() end
RunForce = RunService.Stepped:Connect(function()
--Movement
local RawVel = RopeAttachment.WorldCFrame:VectorToObjectSpace(CharacterGetInputDirection()) --Convert player direction to be relative to the attachment
local Vel = RawVel.X/40 * 10
if RopeAttachment.Position.X + Vel > RopeFrontAttachment.Position.X --[[+ 2]] and RopeAttachment.Position.X + Vel < RopeBackAttachment.Position.X --[[ - 2]] then
RopeAttachment.Position += Vector3.new(Vel, 0, 0)
end
--Attach player to rope
ForceObject.Position = Vector3.new(RopeAttachment.WorldPosition.X, (RopeAttachment.WorldPosition.Y --[[+ Size.Y/2]]) + 3, RopeAttachment.WorldPosition.Z)
--Animate
local Speed = Vel
local Pos = RopeAttachment.Position
if Speed ~= LastSpeed or (Speed == 0 and LastSpeed ~= 0 and Pos == LastPos) then
if AnimEventRun then AnimEventRun:Stop(); AnimEventRun = nil end
if AnimEventIdle then AnimEventIdle:Stop(); AnimEventIdle = nil end
if Speed == 0 or Pos == LastPos then
-- AnimEventIdle = Humanoid.Animator:LoadAnimation(CharUtils.Animations.Idle)
-- AnimEventIdle.Priority = Enum.AnimationPriority.Action
-- AnimEventIdle:Play()
else
--AnimEventRun = Humanoid.Animator:LoadAnimation(CharUtils.Animations.Walk)
--AnimEventRun.Priority = Enum.AnimationPriority.Action
--AnimEventRun:Play()
end
LastSpeed = Speed
LastPos = Pos
end
end)
elseif not RopePart and RopeOnUse then --Trigger off
--Disable
if RunForce then RunForce:Disconnect() end
if AnimEvent then AnimEvent:Disconnect() end
-- if ArmsAnim and AnimEventArms then AnimEventArms:Stop(); AnimEventArms = nil end
if AnimEventRun then AnimEventRun:Stop(); AnimEventRun = nil end
if AnimEventIdle then AnimEventIdle:Stop(); AnimEventRun = nil end
SetForce(false)
--Jump
Humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
--Restore rope pos
LastRopeAttachment.Position = Vector3.new(0, 0, 0)
--End
RopeOnUse = false
task.delay(0.1, function()
RopeOnCooldown = false
end)
end
end
UserInputService.JumpRequest:Connect(function()
if Humanoid.Health > 0 and RopeOnUse then
TriggerRope(false)
end
end)
for _, RopePart in Ropes:GetChildren() do
RopePart.Touched:Connect(function(Hit)
if Hit.Parent == Character then
TriggerRope(RopePart)
end
end)
end
here’s the uncopylocked place with everything set up: