Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local player = game:GetService("Players").LocalPlayer
- local character = player.Character
- local rootPart = character.HumanoidRootPart
- local head = character.Head --lower torso when actual character
- local camera = workspace.CurrentCamera
- local beam1, beam2 = workspace.beam1, workspace.beam2
- local pos1, pos2 = workspace.pos1, workspace.pos2
- local cf = CFrame.new
- local ang = CFrame.Angles
- local v3 = Vector3.new
- local ray = Ray.new
- local sin = math.sin
- local pi = math.pi
- local rad = math.rad
- local deg = math.deg
- local lastUpdate = 0
- local targLeft, targRight = v3(), v3()
- local oldLeft, oldRight = v3(), v3()
- local updateLeft = true
- local leftOff, rightOff = cf(-0.5, -0.5, 0), cf( 0.5, -0.5, 0)
- local lastspeed = 0
- local function getVel()
- local vel = rootPart.CFrame:vectorToObjectSpace(rootPart.Velocity)
- local speed = v3(vel.X, 0, vel.Z).magnitude
- return vel, speed
- end
- local function getDirection()
- local direction = camera.CFrame.lookVector
- local heading = math.atan2(-direction.X, -direction.Z)
- return heading
- end
- local function predictPosition(current, velocity, timeAhead)
- return current * cf(velocity * timeAhead)
- end
- local function getNextPosition(origin, zAngle, xAngle, length)
- local start = origin * ang(zAngle, 0, 0) * ang(0, 0, xAngle)
- local ray = ray(start.p, -start.UpVector * length)
- local hit, pos, nor = workspace:FindPartOnRayWithIgnoreList(ray, {character, beam1, beam2, pos1, pos2, workspace.Ignore})
- return pos
- end
- local function getLegToUpdate(predictedcf, vel)
- local nextLeft = getNextPosition(predictedcf * leftOff, rad(-vel.Z), rad(vel.X), 3)
- local nextRight = getNextPosition(predictedcf * rightOff, rad(-vel.Z), rad(vel.X), 3)
- local relLeft = (predictedcf:PointToObjectSpace((nextLeft + targRight)/2) * v3(1, 0, 1)).magnitude
- local relRight = (predictedcf:PointToObjectSpace((nextRight + targLeft)/2) * v3(1, 0, 1)).magnitude
- if relRight > relLeft then
- return true, nextLeft
- else
- return false, nextRight
- end
- end
- local function updateLegs(leftOrigin, rightOrigin, leftPos, rightPos)
- local d1 = (leftOrigin.p - leftPos).magnitude
- beam1.Size = v3(0.5, 0.5, d1)
- beam1.CFrame = cf(leftOrigin.p, leftPos) * cf(0, 0, -d1/2)
- local d2 = (rightOrigin.p - rightPos).magnitude
- beam2.Size = v3(0.5, 0.5, d2)
- beam2.CFrame = cf(rightOrigin.p, rightPos) * cf(0, 0, -d2/2)
- end
- game:GetService("RunService").RenderStepped:Connect(function(s)
- local vel, speed = getVel()
- local direction = getDirection()
- rootPart.CFrame = cf(rootPart.Position) * ang(0, direction, 0)
- local leftSet, rightSet
- if speed > 0 or math.abs(lastspeed-speed)/s > 0 then
- local delayOf = 0.3
- if lastUpdate + delayOf < tick() then
- lastUpdate = tick()
- local predictedcf = predictPosition(head.CFrame, vel, delayOf)--*1.5)
- local leftLeg, setPos = getLegToUpdate(predictedcf, vel)
- updateLeft = leftLeg
- if leftLeg then
- oldLeft = targLeft
- targLeft = setPos
- else
- oldRight = targRight
- targRight = setPos
- end
- end
- local alpha = math.min((tick()-lastUpdate)/(delayOf/2), 1)
- if updateLeft then
- leftSet = oldLeft:lerp(targLeft, alpha) + v3(0, 0.75*sin(pi*alpha), 0)
- rightSet = targRight
- else
- rightSet = oldRight:lerp(targRight, alpha) + v3(0, 0.75*sin(pi*alpha), 0)
- leftSet = targLeft
- end
- else
- targLeft = getNextPosition(head.CFrame * leftOff, rad(10), rad(-5), 3)
- targRight = getNextPosition(head.CFrame * rightOff, rad(-10), rad(5), 3)
- oldLeft, oldRight = targLeft, targRight
- leftSet, rightSet = targLeft, targRight
- end
- pos1.Position = leftSet
- pos2.Position = rightSet
- updateLegs(head.CFrame * leftOff, head.CFrame * rightOff, leftSet, rightSet)
- lastspeed = speed
- end)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement