Wall run only works on some walls

You can write your topic however you want, but you need to answer these questions:

  1. What do you want to achieve? Keep it simple and clear!

Wallrunning along any wall relative to the rotation of the wall and the raycast that detected it

  1. What is the issue? Include screenshots / videos if possible!

robloxapp-20240409-1318299.wmv (3.3 MB)
The video above better explains it but wall running only works correctly when the walls are to the left and right of the world position

  1. What solutions have you tried so far? Did you look for solutions on the Developer Hub?

I’ve tried using CFrame:ToObjectSpace() but I can’t figure out how to use it correctly in the script.

Thanks for any help here is the script

local c = script.Parent

local holdingKey = false

local Players = game:GetService("Players")

local player = Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()

-- Ensure that the character's humanoid contains an "Animator" object
local humanoid = character:WaitForChild("Humanoid")
local animator = humanoid:WaitForChild("Animator")


local uis = game:GetService("UserInputService")

local leftAnimation = Instance.new("Animation")
leftAnimation.AnimationId = "rbxassetid://17014677879"

-- Wallrun Camera


local CameraService = require(game.ReplicatedStorage.Dependencies.CameraService)
local information = {
	Smoothness = .6,
	CharacterVisibility = "All",
	MinZoom = 10,
	MaxZoom = 10.001, --> To avoid running into math errors, make sure MaxZoom and MinZoom have a difference of at least 0.001.
	Zoom = 10,
	AlignChar = true,
	Offset = CFrame.new(2,0,0),
	LockMouse = true,
	BodyFollow = false
}

local information2 = {
	Smoothness = .6,
	CharacterVisibility = "All",
	MinZoom = 10,
	MaxZoom = 10.001, --> To avoid running into math errors, make sure MaxZoom and MinZoom have a difference of at least 0.001.
	Zoom = 10,
	AlignChar = false,
	Offset = CFrame.new(),
	LockMouse = false,
	BodyFollow = false
}

CameraService:CreateNewCameraView("WallrunCamera", information)
CameraService:CreateNewCameraView("Aim", information)
CameraService:CreateNewCameraView("Unlock", information2)

-- Load the animation onto the animator
local leftAnim = animator:LoadAnimation(leftAnimation)

local rightAnimation = Instance.new("Animation")
rightAnimation.AnimationId = "rbxassetid://17014672160"


-- Load the animation onto the animator
local rightAnim = animator:LoadAnimation(rightAnimation)
rightAnim.Priority= Enum.AnimationPriority.Action2


uis.InputBegan:Connect(function(inp, p)

	if not p and inp.KeyCode == Enum.KeyCode.LeftShift then
		holdingKey = true
	end
end)

uis.InputEnded:Connect(function(inp)
	if inp.KeyCode == Enum.KeyCode.LeftShift then
		CameraService:LockCameraPanning(false, false)
		holdingKey = false
	end
end)
	

game:GetService("RunService").Heartbeat:Connect(function()
	
	local raycastParams = RaycastParams.new()
	raycastParams.FilterType = Enum.RaycastFilterType.Exclude; raycastParams.FilterDescendantsInstances = {c}; raycastParams.IgnoreWater = true
	
	local rayL = workspace:Raycast(c.HumanoidRootPart.CFrame.Position, -c.HumanoidRootPart.CFrame.RightVector * 2.7, raycastParams)
	local rayR = workspace:Raycast(c.HumanoidRootPart.CFrame.Position, c.HumanoidRootPart.CFrame.RightVector * 2.7, raycastParams)
	
	local ray = rayL or rayR
	
	if ray and holdingKey then
		
		if ray == rayL then
			if not leftAnim.IsPlaying then 
				
				leftAnim:Play()
				c.statusHandler.status.Value = "Wallrunning"
				CameraService:SetCameraView("WallrunCamera")
				CameraService:LockCameraPanning(true, true, 90)
			end
			rightAnim:Stop()
		else
			if not rightAnim.IsPlaying then
				rightAnim:Play() 
				c.statusHandler.status.Value = "Wallrunning"
				CameraService:SetCameraView("WallrunCamera")
				CameraService:LockCameraPanning(true, true, 270)
			end
			leftAnim:Stop()
		end
		
		local part = ray.Instance
		
		local weld = c.HumanoidRootPart:FindFirstChild("WallrunWeld") or Instance.new("WeldConstraint")
		weld.Name = "WallrunWeld"
			
		weld.Part0 = c.HumanoidRootPart
		weld.Part1 = part

		local bp = c.HumanoidRootPart:FindFirstChild("WallrunBodyPosition") or Instance.new("BodyPosition", c.HumanoidRootPart)
		bp.Name = "WallrunBodyPosition"
		bp.MaxForce = Vector3.new(math.huge, math.huge, math.huge)
		bp.Position = c.HumanoidRootPart.Position + workspace.CurrentCamera.CFrame.LookVector * 10
			
	else
			
		for i, child in pairs(c.HumanoidRootPart:GetChildren()) do

			if child.Name == "WallrunWeld" or child.Name == "WallrunBodyPosition" then

				child:Destroy()
			end
		end
		c.statusHandler.status.Value = "nil"
		leftAnim:Stop()
		rightAnim:Stop()
	end

end)

The number value in the CameraService:LockCameraPanning(true, true, number) is a rotation value and has to be a number