How Can I go about making a wall run system

I want to make a Wall run system but I have no idea how I’d even do it. What I’m trying to do is make a wall run system where players can run on a wall depending on their LookVector when they are close enough to wall run and also I want to try implement this on curved parts and cylinders basically but I have no idea how I’d constantly orientate it. If anything I just want to know the math behind it or the things I’ll need to know. My first problem was I had when i tried to do this was that when i set humanoid’s auto rotate to false i could still look around when i had shiftlock on and to be honest I have no idea why how would I get the player’s character to stick to a wall and how would I even make them orientate correctly I know I can use things like Align Position and Align Orientation but I have no idea how I can do this, sorry if my explanation is bad i’m not the best at explaining, If anything I just need help knowing concepts behind making a wall run system. Thanks for anyone who responds in advance!

I recently had this same problem when I was trying to make the character walk up ramps. I ended up using render stepped combined with look vector.

-this script would be in startercharacterscripts
--CharacterRotator would be a weld constrainted object to the humanoidrootpart, that would basically be the thing being rotated instead of the humanoid root part.
--why? because when i myself tried it with the humanoid root part it was working weird
local ClosestPoint = WallRunFloor:GetClosestPointOnSurface(script.Parent.HumanoidRootPart.Position)--getting the closest point to the player's humanoid root part.
CharacterRotator.CFrame = CFrame.lookAt(CharacterRotator.Position,ClosestPoint)

You can keep the player from falling off by altering their velocity so they get pushed in the direction the character rotator is facing. and, when adding the character rotator, be sure to make the front face facing downwards, and the top face facing forwards. You cannot orient the player with this strategy, but you can manually face them forward and backward by detecting wether they are getting farther or closer to the end of the wall run by doing

local Distance1=game.Players.LocalPlayer:DistanceFromCharacter(wallrunfloor.endofwallrunpart.Position)
task.wait()
local Distance2=game.Players.LocalPlayer:DistanceFromCharacter(wallrunfloor.endofwallrunpart.Position)

and by comparing which distance is greater, you orient the player based off of that. I know this is a bit hacky, but it works quite well when I used it.

thank you for the reply, but this isn’t quiet the solution I was talking about I understand the auto rotating bit but what im looking for. Now I have a base on what to do and can provide further details on what I want. This video shows how my base is looking, i’m also wondering how do i prevent player from looking around even with shift lock on without actually disabling shift lock even though i’m setting player’s auto rotate to false idk if this video is enough to show you what i mean. I’m yet to apply the force the actually moves the player foward yet

function WallRunModule:WallRunBegin()
	if wallRunning == true then return end
--	wallRunning = true

	-- Initial raycast for wall detection.
	local hit, Direction, wallDirVal = raycastWall()
	if not hit then
		warn("No wall detected.")
		return
	end
	
	local wallAttachment = getOrCreateAttachment(RootPart, "WallRunAttachment")
	
	local alignPosition = Instance.new("AlignPosition")
	alignPosition.Attachment0 = wallAttachment
	alignPosition.Mode = Enum.PositionAlignmentMode.OneAttachment
	alignPosition.RigidityEnabled = true
	alignPosition.MaxForce = 10000
	alignPosition.MaxVelocity = 100
	alignPosition.Responsiveness = 200
	alignPosition.Parent = RootPart

	local alignOrientation = Instance.new("AlignOrientation")
	alignOrientation.Attachment0 = wallAttachment
	alignOrientation.Mode = Enum.OrientationAlignmentMode.OneAttachment
	alignOrientation.RigidityEnabled = true
	alignOrientation.MaxTorque = 10000
	alignOrientation.Responsiveness = 200
	alignOrientation.Parent = RootPart

	local vectorForce = Instance.new("VectorForce")
	vectorForce.Force = Vector3.new(0,-1,0)
	vectorForce.Attachment0 = wallAttachment
	vectorForce.RelativeTo = Enum.ActuatorRelativeTo.World
	vectorForce.ApplyAtCenterOfMass = true
	vectorForce.Parent = RootPart

	local wallHitPos = hit.Position
	local wallNormal = hit.Normal
	
	_G.Animations["WallRun"..Direction]:Play()
	Humanoid.PlatformStand = true
	
	connections[player] = RunService.RenderStepped:Connect(function()
		
		hit = raycastWall()
		if not hit then
			_G.Animations["WallRun"..Direction]:Stop()
			alignOrientation:Destroy()
			vectorForce:Destroy()
			alignPosition:Destroy()
			connections[player]:Disconnect()
			connections[player] = nil
			Humanoid.PlatformStand = false
			return
		end

		local forwardDirection = RootPart.CFrame.LookVector
		local rightDirection = forwardDirection:Cross(wallNormal).Unit
		local upDirection = rightDirection:Cross(forwardDirection).Unit
		local newCFrame = CFrame.fromMatrix(RootPart.Position, rightDirection, upDirection)
		
		Humanoid.AutoRotate = false
		Humanoid.PlatformStand = true
		alignPosition.Position =  wallHitPos + wallNormal * Wall_Offset 
		
	end)
	

end

this is basically my, code for it

I see. I don’t really know how you could deal with shift lock being enabled. I am not the most experienced coder, I just happened to find that solution to my problem. sorry if its not what you were looking for. I don’t exactly know what you might be wanting, so if you explain it better I might be able to help you.

What I want to do is orientate the player across the wall correctly as shown in the video which works but I also want the player to go foward across the wall

alignPosition.Position =  (wallHitPos + wallNormal * Wall_Offset) + RootPart.CFrame.LookVector * self.WallRunInfo.WallRunSpeed

this is how im setting the align position nothing else has changed i dont want the Y axis to be affected but when i set the cframeMatrix vY position to vector.new(0,0,0) that didnt work too so ima kinda at a loss of what to do. Again sorry if im explaining badly could you point out what im not explaining well and i’ll try my best to explain it better

try splitting your LookVector into just the X and Z parts so you don’t mess with the Y axis.

local flatLook = Vector3.new(RootPart.CFrame.LookVector.X, 0, RootPart.CFrame.LookVector.Z).Unit

then use that flatLook for moving the player forward. Shift lock can still be a pain even with AutoRotate off, so you might need a quick camera script tweak to lock it down properly.
Also, check out the AlignPosition and AlignOrientation docs on the Roblox Dev Hub for more ideas

I’ve managed to make a system that im proud of thank both of you for the help. If anyone reading this on the future and is stuck making a wall run system lmk and i’ll try to help as much as i can