Hello! So I’m working on a Wall Running mechanic and I found a glitch. I tried a few ways to fix it however none of these works so I’m asking if anyone else knows how to fix it. Basically if you wall run into a wall it rapidly rotates the player then they get flung, and I’m just curious if anyone knows why and how to fix it. Thanks!
Video of Issue:
It usually wont send you that far but sometimes you can literally get sent hundreds of studs.
Both scripts are in StarterCharacterScripts as well.
Wall Run Script:
-- Settings --
local Speed = 4000
local Gravity = 0
local MaxWallrunRadius = 4
local CameraTiltAmount = 15
local Cooldown = 0.75
local RightAnimId = "rbxassetid://83121519454876"
local LeftAnimId = "rbxassetid://124890838985456"
-- References --
local char = script.Parent
local plr = game.Players:GetPlayerFromCharacter(char)
local HRP: Part = char:WaitForChild("HumanoidRootPart")
local hum = char:WaitForChild("Humanoid")
-- Raycast Parameters --
local params = RaycastParams.new()
params.FilterType = Enum.RaycastFilterType.Exclude
params.FilterDescendantsInstances = {char}
-- Attachments and Physics --
local Attach = Instance.new("Attachment")
Attach.Parent = HRP
local Velocity = Instance.new("LinearVelocity")
Velocity.MaxForce = math.huge
Velocity.Enabled = false
Velocity.Attachment0 = Attach
Velocity.Parent = HRP
-- Signal and RunService --
local Signal = script.Parent:WaitForChild("WallrunSignal")
local RS = game:GetService("RunService")
local UserInputService = game:GetService("UserInputService")
-- State Variables --
local Wallrunning = false
local WallrunningNormal = Vector3.new(0, 0, 0)
local lastWallrun = 0
-- Wallrun Animations --
local rightWallrunAnim = Instance.new("Animation")
rightWallrunAnim.AnimationId = RightAnimId
local rightAnimTrack = hum:WaitForChild("Animator"):LoadAnimation(rightWallrunAnim)
local leftWallrunAnim = Instance.new("Animation")
leftWallrunAnim.AnimationId = LeftAnimId
local leftAnimTrack = hum:WaitForChild("Animator"):LoadAnimation(leftWallrunAnim)
-- Wallrun Request Handling --
Signal.OnServerEvent:Connect(function(plr, val)
if hum:GetState() ~= Enum.HumanoidStateType.Freefall then return end
if val then
if tick() - lastWallrun < Cooldown then return end
lastWallrun = tick()
local right = workspace:Raycast(HRP.Position, HRP.CFrame.RightVector * MaxWallrunRadius, params)
if right then
Wallrunning = 1
WallrunningNormal = Vector3.new(right.Normal.Z, 0, -right.Normal.X)
Signal:FireClient(plr, CameraTiltAmount)
rightAnimTrack:Play()
else
local left = workspace:Raycast(HRP.Position, -HRP.CFrame.RightVector * MaxWallrunRadius, params)
if left then
Wallrunning = -1
WallrunningNormal = Vector3.new(left.Normal.Z, 0, -left.Normal.X)
Signal:FireClient(plr, -CameraTiltAmount)
leftAnimTrack:Play()
end
end
elseif Wallrunning then
Wallrunning = false
Velocity.Enabled = false
Signal:FireClient(plr, 0)
Velocity.VectorVelocity = Vector3.new(0, 0, 0)
rightAnimTrack:Stop()
leftAnimTrack:Stop()
end
end)
-- Frame Updates --
RS.Heartbeat:Connect(function(dt)
if hum:GetState() ~= Enum.HumanoidStateType.Freefall and hum:GetState() ~= Enum.HumanoidStateType.FallingDown then
Wallrunning = false
end
if Wallrunning then
Velocity.Enabled = true
local result = workspace:Raycast(HRP.Position, HRP.CFrame.RightVector * MaxWallrunRadius * Wallrunning, params)
if result then
local v = WallrunningNormal * Speed * -Wallrunning * dt
Velocity.VectorVelocity = Vector3.new(v.X, -Gravity, v.Z)
else
Wallrunning = false
end
elseif Velocity.Enabled then
Velocity.Enabled = false
Signal:FireClient(plr, 0)
Velocity.VectorVelocity = Vector3.new(0, 0, 0)
rightAnimTrack:Stop()
leftAnimTrack:Stop()
end
end)
Wall Run Local Script:
-- Settings --
local TiltSpeed = 1
local JumpPower = 500
-- References --
local Signal = script.Parent:WaitForChild("WallrunSignal")
local UIS = game:GetService("UserInputService")
local RS = game:GetService("RunService")
local Goal = 0
local CurrentAngle = 0
local cam = workspace.CurrentCamera
local HRP: Part = script.Parent:WaitForChild("HumanoidRootPart")
-- Input Handling --
UIS.InputBegan:Connect(function(key, p)
if not p then
if key.KeyCode == Enum.KeyCode.T then
Signal:FireServer(true) -- Start wallrunning
elseif key.KeyCode == Enum.KeyCode.R then
Signal:FireServer(false) -- Stop wallrunning
end
end
end)
UIS.InputEnded:Connect(function(key, p)
if not p and key.KeyCode == Enum.KeyCode.T then
Signal:FireServer(false) -- Stop wallrunning when T is released
end
end)
-- Wallrun Signal --
Signal.OnClientEvent:Connect(function(angle)
Goal = angle
if angle == 0 then
HRP:ApplyImpulse(Vector3.new(0, JumpPower, 0)) -- Jump off the wall when wallrunning ends
end
end)
-- Camera Tilt Update --
RS.RenderStepped:Connect(function()
local sign = Goal / math.abs(Goal) -- Determine direction of tilt
if CurrentAngle * sign < Goal * sign then
CurrentAngle += sign * TiltSpeed
elseif CurrentAngle ~= 0 then
sign = CurrentAngle / math.abs(CurrentAngle)
CurrentAngle -= sign * TiltSpeed
end
if math.abs(CurrentAngle - Goal) <= TiltSpeed then
CurrentAngle = Goal
end
cam.CFrame *= CFrame.Angles(0, 0, math.rad(CurrentAngle))
end)
Thanks again!