You were on the right track with the Ray, but I would use Raycast. You need the Unit for the direction, and the distance to get the correct covered area.
firearm.Equipped:Connect(function(mouse, character)
-- Stop clipping through walls
--local cameraRay = Ray.new(character.Head.Position, camera.CFrame.Position - character.Head.Position)
--local ignore = {character}
camera.CameraType = Enum.CameraType.Scriptable
userInputService.MouseBehavior = Enum.MouseBehavior.LockCenter
local character = player.Character
local humanoid = character:WaitForChild("Humanoid")
local humanoidRootPart = character:WaitForChild("HumanoidRootPart")
local cameraAngleX = 0
local cameraAngleY = 0
local function playerInput(actionName, inputState, inputObject)
if inputState == Enum.UserInputState.Change then
cameraAngleX -= inputObject.Delta.X
cameraAngleY = math.clamp(cameraAngleY - inputObject.Delta.Y * 0.4, -40, 40) -- Change 0.4 if needed
end
end
contextActionService:BindAction("PlayerInput", playerInput, false, Enum.UserInputType.MouseMovement, Enum.UserInputType.Touch)
runService:BindToRenderStep("CameraUpdate", Enum.RenderPriority.Camera.Value, function()
local startCFrame = CFrame.new(humanoidRootPart.CFrame.Position) * CFrame.Angles(0, math.rad(cameraAngleX), 0) * CFrame.Angles(math.rad(cameraAngleY), 0, 0)
local cameraCFrame = startCFrame:PointToWorldSpace(cameraOffSet)
local cameraFocus = startCFrame:PointToWorldSpace(Vector3.new(cameraOffSet.X, cameraOffSet.Y, -1000000))
camera.CFrame = CFrame.lookAt(cameraCFrame, cameraFocus)
local lookingCFrame = CFrame.lookAt(humanoidRootPart.Position, camera.CFrame:PointToWorldSpace(Vector3.new(0, 0, -100000)))
humanoidRootPart.CFrame = CFrame.fromMatrix(humanoidRootPart.Position, lookingCFrame.XVector, humanoidRootPart.CFrame.YVector)
local rayparams = RaycastParams.new()
rayparams.FilterDescendantsInstances = {character}
rayparams.FilterType = Enum.RaycastFilterType.Blacklist
local origin = character.Head.CFrame.Position
local ray = workspace:Raycast(origin, (origin - camera.CFrame.Position).Unit * (origin - camera.CFrame.Position).magnitude, rayparams)
if ray then
camera.CFrame = ray.Position
end
end)
end)