Wall Run Glitch

I have a pretty basic wall run script, however, you can use it in my custom water. I don’t want this, I’ve tried fixing it but haven’t been able to get it to work. Any ideas on how to do this? Thanks.

The Wall Run scripts are in StarterCharacterScripts and the Swim Script is in replicated first

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 = 100000 -- Adjusted max force here
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)

Swim (Local Script):

-- Services
local replicatedStorage = game:GetService("ReplicatedStorage")
local inputService = game:GetService("UserInputService")
local runService = game:GetService("RunService")
local playerService = game:GetService("Players")
local lighting = game:GetService("Lighting")
local physicsService = game:GetService("PhysicsService")
local TweenService = game:GetService("TweenService")

-- Vars
local player = playerService.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local humanoidRootPart = character:WaitForChild("HumanoidRootPart")
local humanoid = character:WaitForChild("Humanoid")
local diveCorrection = lighting:WaitForChild("DiveCorrection")
local diveBlur = lighting:WaitForChild("DiveBlur")
local seaValue = script:WaitForChild("SeaValue")
local sea = seaValue.Value
local ocean = sea:WaitForChild("Ocean")
local sand = sea:WaitForChild("Sand")

-- LocalVars
local swimPosition = nil
local swimming = false
local canJump = false
local originalGravity = workspace.Gravity -- Store the original gravity
local swimIdleTrack = humanoid:LoadAnimation(game.ReplicatedFirst.Animations.SwimIdle)
local swimMovingTrack = humanoid:LoadAnimation(game.ReplicatedFirst.Animations.SwimMoving)
local bobbingUp = true -- Tracks bobbing direction

-- Helper Functions
local function stopSwimming()
	swimming = false
	character:SetAttribute("Swimming", false)
	if swimIdleTrack.IsPlaying then swimIdleTrack:Stop() end
	if swimMovingTrack.IsPlaying then swimMovingTrack:Stop() end
	if swimPosition then
		swimPosition:Destroy()
		swimPosition = nil
	end
end

local function startSwimming()
	swimming = true
	character:SetAttribute("Swimming", true)
	if not swimIdleTrack.IsPlaying then
		swimIdleTrack:Play()
	end
end

local function tweenBobbing(targetPosition)
	if swimPosition then
		local tweenInfo = TweenInfo.new(0.25, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut)
		local tween = TweenService:Create(swimPosition, tweenInfo, {Position = targetPosition})
		tween:Play()
	end
end

-- Character Added
player.CharacterAdded:Connect(function(char)
	character = char
	humanoidRootPart = char:WaitForChild("HumanoidRootPart")
	humanoid = char:WaitForChild("Humanoid")
	swimPosition = nil
	swimming = false
	canJump = false
	swimIdleTrack = humanoid:LoadAnimation(game.ReplicatedFirst.Animations.SwimIdle)
	swimMovingTrack = humanoid:LoadAnimation(game.ReplicatedFirst.Animations.SwimMoving)
	ocean.Position = Vector3.new(humanoidRootPart.Position.X, ocean.Position.Y, humanoidRootPart.Position.Z)
	sand.Position = Vector3.new(humanoidRootPart.Position.X, sand.Position.Y, humanoidRootPart.Position.Z)
	char:SetAttribute("Swimming", false)
end)

-- Ocean Touch Event (Player Enters Water)
ocean.Touched:Connect(function(otherPart)
	if swimming then return end
	if otherPart.Parent == character and otherPart == character.PrimaryPart then
		startSwimming()

		swimPosition = Instance.new("BodyPosition")
		swimPosition.MaxForce = Vector3.new(0, 100000, 0)
		swimPosition.Position = Vector3.new(0, ocean.Position.Y + 7.5, 0)
		swimPosition.Parent = humanoidRootPart
		canJump = true

		-- Start smooth bobbing effect
		task.spawn(function()
			while swimming do
				if swimPosition then
					-- Determine target position for bobbing
					local bobbingOffset = bobbingUp and 0.25 or -0.25
					local newPosition = swimPosition.Position + Vector3.new(0, bobbingOffset, 0)

					-- Tween to the new position
					tweenBobbing(newPosition)

					-- Toggle direction
					bobbingUp = not bobbingUp
				end
				task.wait(0.25) -- Wait for 0.25 seconds
			end
		end)
	end
end)

-- Jump Request (Leave Water)
inputService.JumpRequest:Connect(function()
	if swimming and canJump then
		-- Stop swimming and remove BodyPosition
		stopSwimming()

		-- Temporarily adjust gravity and apply upward force
		workspace.Gravity = 150 -- Lower gravity for a smoother jump
		humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
		humanoidRootPart.Velocity = Vector3.new(0, 75, 0) -- Increased upward velocity

		-- Restore gravity after a delay
		task.delay(0.5, function()
			workspace.Gravity = originalGravity
		end)
	end
end)

-- Detect movement and switch between animations
runService.RenderStepped:Connect(function()
	if swimming then
		local moveDirection = humanoid.MoveDirection
		if moveDirection.Magnitude > 0 then
			-- Player is moving
			if not swimMovingTrack.IsPlaying then
				swimIdleTrack:Stop() -- Ensure idle animation stops
				swimMovingTrack:Play()
			end
			-- Elevate the player slightly when moving
			if swimPosition then
				swimPosition.Position = Vector3.new(humanoidRootPart.Position.X, ocean.Position.Y + 8.0, humanoidRootPart.Position.Z)
			end
		else
			-- Player is idle
			if not swimIdleTrack.IsPlaying then
				swimMovingTrack:Stop() -- Ensure moving animation stops
				swimIdleTrack:Play()
			end
			-- Lower the player's position slightly when idle
			if swimPosition then
				swimPosition.Position = Vector3.new(humanoidRootPart.Position.X, ocean.Position.Y + 7.5, humanoidRootPart.Position.Z)
			end
		end
	end
end)

-- Update ocean and sand positions
runService.RenderStepped:Connect(function()
	if character then
		local humanoidRootPart = character:FindFirstChild("HumanoidRootPart")
		if humanoidRootPart then
			local distCheck = (character:GetPivot().Position - ocean.Position).Magnitude
			if distCheck >= 750 then
				ocean.Position = Vector3.new(humanoidRootPart.Position.X, ocean.Position.Y, humanoidRootPart.Position.Z)
				sand.Position = Vector3.new(humanoidRootPart.Position.X, sand.Position.Y, humanoidRootPart.Position.Z)
			end
		end
	end

	local camera = workspace.CurrentCamera
	if camera.CFrame.Y < ocean.Position.Y + 8 then
		diveBlur.Enabled = true
		diveCorrection.Enabled = true
	else
		diveBlur.Enabled = false
		diveCorrection.Enabled = false
	end
end)

Could you send a video of how it doesn’t work? You could double check you exclude it from any raycasting, or include it and disable the system when it is detected.