Issue with raycasting for camera script

A while ago I made a camera script similar to shift lock and I was very proud of it but there was stuff missing. One of those thing was that it would go through walls so I tried to fix that with some raycasting.

The current issue is that the ray check only works in the positive Z direction.
https://twitter.com/NeonD00m/status/1275879908342771712

Here is my script! the function that does the raycast is rayCheck().

-- SERVICES/IMPORTANT STUFF
local Input = game:GetService("UserInputService")
	Input.MouseBehavior = Enum.MouseBehavior.LockCenter
local cam = workspace.CurrentCamera
	cam.CameraType = Enum.CameraType.Scriptable

-- INSTANCES
local plr = game.Players.LocalPlayer
local mouse = plr:GetMouse()
local char = plr.Character or plr.CharacterAdded:Wait()
local camroot = char:WaitForChild("HumanoidRootPart")
local root = char:WaitForChild("HumanoidRootPart")

-- VARIABLES
local senseX = 0.01
local senseY = 0.01
local roll = 0
local lastCFrame = CFrame.new()
	local lX = 0
	local lY = 0
local primaryOffset = CFrame.new(2, 1.75, 0)--affects raycast starting point
local mainOffset = CFrame.new(0, 0, 5)--affects camera end point


local check = function(cX)
	local newX = cX
	local checked = false
	if newX > math.rad(90) then
		newX = math.rad(90)
		checked = true
	elseif newX < math.rad(-90) then
		newX = math.rad(-90)
		checked = true
	end
	return CFrame.fromEulerAnglesXYZ(newX, 0, 0), checked
end

local function rayCheck(startPoint, endPoint, rotation)
	local ray = Ray.new(startPoint.Position, endPoint.Position)
	local dontCare, hit = workspace:FindPartOnRay(ray, char)
	if hit == nil or (startPoint.Position - hit).Magnitude > (startPoint.Position - endPoint.Position).Magnitude then
		return endPoint
	else
		local dist = (startPoint.Position - hit).Magnitude
		return startPoint * CFrame.new(0, 0, dist)
	end
end

local function RenderCamera()
	char.Humanoid.AutoRotate = false
	Input.MouseBehavior = Enum.MouseBehavior.LockCenter
	
	local mDelta = Input:GetMouseDelta() * -1
	
	local cX = senseY * mDelta.Y + lX
	local cY = senseX * mDelta.X + lY
	
	local newRootCF = CFrame.new(root.Position.X, root.Position.Y, root.Position.Z) * CFrame.fromEulerAnglesXYZ(0, cY, 0)
	root.CFrame = newRootCF
	
	local headPos = camroot.CFrame
	
	if math.abs(mDelta.X) > 0 or math.abs(mDelta.Y) > 0 then
		local deltaCF, checked = check(cX)
		local startPoint = headPos * primaryOffset * deltaCF
		local endPoint = startPoint * mainOffset
		
		local endCFrame = rayCheck(startPoint, endPoint, deltaCF)
		
		cam.CFrame = endCFrame
		lastCFrame = deltaCF
		if not checked then
			lX = cX
			lY = cY
		end
	else
		local startPoint = headPos * primaryOffset * lastCFrame
		local endPoint = startPoint * mainOffset
		
		local endCFrame = rayCheck(startPoint, endPoint, lastCFrame)
		
		cam.CFrame = endCFrame
	end
end

Input.InputBegan:Connect(function(key)
	if key.KeyCode == Enum.KeyCode.Q then
		game:GetService("RunService"):UnbindFromRenderStep("myCamera")
		Input.MouseBehavior = Enum.MouseBehavior.Default
		cam.CameraType = Enum.CameraType.Custom
	end
end)
Input.InputEnded:Connect(function(key)
	if key.KeyCode == Enum.KeyCode.Q then
		cam.CameraType = Enum.CameraType.Scriptable
		game:GetService("RunService"):BindToRenderStep("myCamera", Enum.RenderPriority.Camera.Value + 1, RenderCamera)
	end
end)

game:GetService("RunService"):BindToRenderStep("myCamera", Enum.RenderPriority.Camera.Value + 1, RenderCamera)

Hey Neon,
After looking at this script, I think you are confused with how raycasting works.
Ray.new() takes in a Vector3 origin and a Vector3 direction.

In your script you are trying to use the endPosition.

The correct script would be

-- SERVICES/IMPORTANT STUFF
local Input = game:GetService("UserInputService")
	Input.MouseBehavior = Enum.MouseBehavior.LockCenter
local cam = workspace.CurrentCamera
	cam.CameraType = Enum.CameraType.Scriptable

-- INSTANCES
local plr = game.Players.LocalPlayer
local mouse = plr:GetMouse()
local char = plr.Character or plr.CharacterAdded:Wait()
local camroot = char:WaitForChild("HumanoidRootPart")
local root = char:WaitForChild("HumanoidRootPart")

-- VARIABLES
local senseX = 0.01
local senseY = 0.01
local roll = 0
local lastCFrame = CFrame.new()
	local lX = 0
	local lY = 0
local primaryOffset = CFrame.new(2, 1.75, 0)--affects raycast starting point
local mainOffset = CFrame.new(0, 0, 5)--affects camera end point


local check = function(cX)
	local newX = cX
	local checked = false
	if newX > math.rad(90) then
		newX = math.rad(90)
		checked = true
	elseif newX < math.rad(-90) then
		newX = math.rad(-90)
		checked = true
	end
	return CFrame.fromEulerAnglesXYZ(newX, 0, 0), checked
end

local function rayCheck(startPoint, endPoint, rotation)
	local ray = Ray.new(startPoint.Position, (endPoint.Position-startPoint.Position).unit*5)
	local dontCare, hit = workspace:FindPartOnRay(ray, char)
	if hit == nil or (startPoint.Position - hit).Magnitude > (startPoint.Position - endPoint.Position).Magnitude then
		return endPoint
	else
		local dist = (startPoint.Position - hit).Magnitude
		return startPoint * CFrame.new(0, 0, dist)
	end
end

local function RenderCamera()
	char.Humanoid.AutoRotate = false
	Input.MouseBehavior = Enum.MouseBehavior.LockCenter
	
	local mDelta = Input:GetMouseDelta() * -1
	
	local cX = senseY * mDelta.Y + lX
	local cY = senseX * mDelta.X + lY
	
	local newRootCF = CFrame.new(root.Position.X, root.Position.Y, root.Position.Z) * CFrame.fromEulerAnglesXYZ(0, cY, 0)
	root.CFrame = newRootCF
	
	local headPos = camroot.CFrame
	
	if math.abs(mDelta.X) > 0 or math.abs(mDelta.Y) > 0 then
		local deltaCF, checked = check(cX)
		local startPoint = headPos * primaryOffset * deltaCF
		local endPoint = startPoint * mainOffset
		
		local endCFrame = rayCheck(startPoint, endPoint, deltaCF)
		
		cam.CFrame = endCFrame
		lastCFrame = deltaCF
		if not checked then
			lX = cX
			lY = cY
		end
	else
		local startPoint = headPos * primaryOffset * lastCFrame
		local endPoint = startPoint * mainOffset
		
		local endCFrame = rayCheck(startPoint, endPoint, lastCFrame)
		
		cam.CFrame = endCFrame
	end
end

Input.InputBegan:Connect(function(key)
	if key.KeyCode == Enum.KeyCode.Q then
		game:GetService("RunService"):UnbindFromRenderStep("myCamera")
		Input.MouseBehavior = Enum.MouseBehavior.Default
		cam.CameraType = Enum.CameraType.Custom
	end
end)
Input.InputEnded:Connect(function(key)
	if key.KeyCode == Enum.KeyCode.Q then
		cam.CameraType = Enum.CameraType.Scriptable
		game:GetService("RunService"):BindToRenderStep("myCamera", Enum.RenderPriority.Camera.Value + 1, RenderCamera)
	end
end)

game:GetService("RunService"):BindToRenderStep("myCamera", Enum.RenderPriority.Camera.Value + 1, RenderCamera)

I didn’t know raycasting worked like that, I’ll see if that works.