How would I start wallrun movement?

Hey, I am making a wallrun script and everything is going fine but i’m having problems figuring out on how to start on the movement of wallrun. I can’t use body velocity because my movement script doesn’t support it,

--[ Services ]--
local Players = game:GetService("Players")
local UserInputService = game:GetService("UserInputService")
local GuiService = game:GetService("GuiService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Player: Player = Players.LocalPlayer
local Character = Player.CharacterAdded:Wait() or Player.Character
local Head = Character:WaitForChild("Head")
local Root = Character:WaitForChild("HumanoidRootPart")
local Humanoid = Character:WaitForChild("Humanoid")
local Camera = workspace.CurrentCamera

local RaycastParameters = RaycastParams.new()
RaycastParameters.FilterType = Enum.RaycastFilterType.Blacklist
RaycastParameters.FilterDescendantsInstances = {Character}

--[ Modules ]--
local CustomWait = require(ReplicatedStorage.Modules.Extra["Custom Wait"])
--[ Settings ]--
local DEBUG_MODE = true
local RAY_LENGTH = 2
local FLOOR_RAY_LENGTH = 7
local TIME_DELAY = 0.2
local END_TIME = 2

local LastSpacePressed = tick()

--[ Auxiliary Functions ]--
local function DebugAttatchment(Position: Vector3)
	if not DEBUG_MODE then return end

	local DebugPoint = Instance.new("Attachment") 
	DebugPoint.Visible = true
	
	DebugPoint.CFrame = CFrame.new(Position)
	DebugPoint.Parent = workspace.Terrain

	task.delay(5, function()
		DebugPoint:Destroy()
	end)

	print("DEBUG: Wallrun began on "..tostring(Position))
end

local function LeftWallCheck()
	return workspace:Raycast(Root.Position, -Root.CFrame.RightVector * RAY_LENGTH, RaycastParameters)
end

local function RightWallCheck()
	return workspace:Raycast(Root.Position, Root.CFrame.RightVector * RAY_LENGTH, RaycastParameters)
end

local function FloorCheck()
	return workspace:Raycast(Root.Position, -Root.CFrame.UpVector * RAY_LENGTH, RaycastParameters)
end

--[ Main Functions ]--

function Wallrun()
	if not LeftWallCheck() and not RightWallCheck() then return end -- needs to go through these casts first.
	
	local Speed = Character:WaitForChild("Humanoid").WalkSpeed -- only works because of movement module

	if Speed > 14 then -- can't wallrun if no speed
		if LeftWallCheck() then
			DebugAttatchment(LeftWallCheck().Position)
			
			Root.Anchored = true
			Humanoid.AutoRotate = false
			
			task.wait(END_TIME)
			
			Root.Anchored = false
			Humanoid.AutoRotate = true
			
			--TODO: add wallrun physics
		else
			DebugAttatchment(RightWallCheck().Position)
			
			Root.Anchored = true
			Humanoid.AutoRotate = false

			task.wait(END_TIME)

			Root.Anchored = false
			Humanoid.AutoRotate = true
			
			--TODO: add wallrun physics
		end
	end

end

function OnJump(Input,Processed) 
	if Processed then return end
	if Input.KeyCode == Enum.KeyCode.Space then
		if tick() - LastSpacePressed <= TIME_DELAY then
			Wallrun()
		else
			LastSpacePressed = tick()
		end
	end
end

UserInputService.InputBegan:Connect(OnJump)

Camera.ChildAdded:Connect(function(Child)
	if Child.Name == "Viewmodel" then
		RaycastParameters.FilterDescendantsInstances = {Character,Child}
	end
end)

Anything will help, thank you for reading.

im not good at scripting but maybe make like a hitbox and if the hitbox is touching the walls with a specific name and last jump was x seconds ago make you fall slower and get more speed while touching the walls

Hello,

If you can’t use BodyVelocity, you might want to consider using Humanoid:ChangeState(), or Humanoid.MoveDirection. Humanoid:ChangeState() changes the state of the humanoid to states like “Jumping”, “Climbing”, and “Running”.

Humanoid.MoveDirection applies a directional force to the humanoid. This can be used to make the character move along the wall. Here’s a basic example:

-- in your wallrun function
if LeftWallCheck() then
    DebugAttatchment(LeftWallCheck().Position)
    
    Root.Anchored = true
    Humanoid.AutoRotate = false
    
    Humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
    Humanoid.MoveDirection = Root.CFrame.LookVector + Vector3.new(0, 1, 0)
    
    task.wait(END_TIME)
    
    Root.Anchored = false
    Humanoid.AutoRotate = true
    Humanoid.MoveDirection = Vector3.new(0, 0, 0)
end

The above example assumes the wall is to the left of the character. It sets the MoveDirection to the forward direction of the character (along the wall) and upward. This will make the character appear to be running along the wall. You’ll need to adjust the direction and magnitude to fit your game.
note that Humanoid.MoveDirection is a continuous force, so you’ll need to reset it to Vector3.new(0, 0, 0) when you’re done.

Remember to adjust the direction and force according to your game’s specifics. Wall running is a complex mechanic and might need several iterations and adjustments to get just right.

I hope this helps! If you have any other questions or need further clarification, feel free to ask.

1 Like

I already got the wall raycasts working, that means it already detects left and right walls, all I need to do is add physics.