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)