How can I apply a 'Popper' to OTC Camera?

Hi I’m working on a Custom OTC camera system.
However, I’m struggling to find a way to implement a popper - I don’t want the Camera having the ability to see through parts.

I’ve attached the code & a copy of the module.
Any help would be appreciated, thank you.

  local Core = {Server = game, Self = script}
  
  local UserInputService = Core.Server:GetService("UserInputService")
  local RunService = Core.Server:GetService("RunService")
  local TweenService = Core.Server:GetService("TweenService")
  
  local Player = {...}
  Player.Self = Core.Server:GetService("Players").LocalPlayer
  Player.Character = nil
  Player.HumanoidRootPart = nil
  
  local Camera = {...}
  Camera.Self = Core.Server:GetService("Workspace"):WaitForChild("Camera")
  Camera.xAngle, Camera.yAngle = 0, 0
  Camera.Sensitivity = 0.2
  Camera.Offset = Instance.new("Vector3Value")
  Camera.Offset.Value = Vector3.new(2.5, 0.5, 8)
  
  local Crosshair = Player.Self.PlayerGui:WaitForChild("Crosshair")
  local Highlight = Crosshair:WaitForChild("Highlight")
  Crosshair.Enabled = false
  
  local Connection = {...}

--[--]--[--]--
--[--]--[--]--

  function Core:Tween(Obj, Info, Properties, ...)
    local Tween = nil
    
    if Tween ~= nil then
      Tween:Pause(...)
      Tween:Cancel(...)
    end
    
    Tween = TweenService:Create(Obj, Info, Properties)
    
    return Tween
  end

--[--]--[--]--
--[--]--[--]--

  function InputChanged(...)
    Connection.InputChanged = UserInputService.InputChanged:Connect(function(Input, GP, ...)
      if Input.UserInputType == Enum.UserInputType.MouseMovement then
        Camera.xAngle = Camera.xAngle-Input.Delta.x*Camera.Sensitivity
        Camera.yAngle = math.clamp(Camera.yAngle-Input.Delta.y*Camera.Sensitivity,-80,80)
      end
    end)
  end

--[--]--[--]--
--[--]--[--]--

  function SetCamera(...)
    Connection.onChange = Core.Self:GetAttributeChangedSignal("isHolding"):Connect(function(...)
      if Core.Self:GetAttribute("isHolding") then
        Core:Tween(Camera.Offset, TweenInfo.new(0.5), {Value = Vector3.new(2, 0.5, 5)}):Play(...)
      else
        Core:Tween(Camera.Offset, TweenInfo.new(0.5), {Value = Vector3.new(2.5, 0.5, 8)}):Play(...)
      end
    end)
    
    Connection.SetCamera = RunService.RenderStepped:Connect(function(...)
      Player.Character = Player.Self.Character
      Player.HumanoidRootPart = Player.Character:FindFirstChild("HumanoidRootPart")
      
      local mousePosition = UserInputService:GetMouseLocation()
      local unitRay = Camera.Self:ScreenPointToRay(mousePosition.X, mousePosition.Y)

      local rayParams = RaycastParams.new()
      rayParams.FilterDescendantsInstances = {Player.Self.Character}
      rayParams.FilterType = Enum.RaycastFilterType.Blacklist

      local rayResult = workspace:Raycast(unitRay.Origin, unitRay.Direction * 500, rayParams)
      if rayResult then
        if rayResult.Instance.Parent.ClassName == "Model" and rayResult.Instance.Parent:FindFirstChild("Humanoid") then
          Highlight.Adornee = rayResult.Instance.Parent
          Highlight.Enabled = true
        else
          Highlight.Adornee = nil
          Highlight.Enabled = false
        end
      end
      
      if Player.Character and Player.HumanoidRootPart then
        local startCFrame = CFrame.new((Player.HumanoidRootPart.CFrame.p + Vector3.new(0,2,0)))*CFrame.Angles(0, math.rad(Camera.xAngle), 0)*CFrame.Angles(math.rad(Camera.yAngle), 0, 0)
        
        local cameraCFrame = startCFrame + startCFrame:vectorToWorldSpace(Camera.Offset.Value)
        local cameraFocus = startCFrame + startCFrame:vectorToWorldSpace(Vector3.new(Camera.Offset.Value.X, Camera.Offset.Value.Y, -50000))

        Camera.Self.CFrame = CFrame.new(cameraCFrame.p,cameraFocus.p)
        
        if Core.Self:GetAttribute("isHolding") then
          Player.HumanoidRootPart.CFrame = CFrame.new(Player.HumanoidRootPart.CFrame.p, Player.HumanoidRootPart.CFrame.p + Vector3.new(Camera.Self.CFrame.LookVector.X,0,Camera.Self.CFrame.LookVector.Z))
        end
      end
    end)
  end

--[--]--[--]--
--[--]--[--]--

  function Core:Enable(...)
    Crosshair.Enabled = true
    Camera.Self.CameraType = Enum.CameraType.Scriptable
    UserInputService.MouseBehavior = Enum.MouseBehavior.LockCenter
    UserInputService.MouseIconEnabled = false
    InputChanged(...)
    SetCamera(...)
  end

--[--]--[--]--
--[--]--[--]--

  function Core:Disable(...)
    Crosshair.Enabled = false
    Highlight.Enabled = false
    Camera.Self.CameraType = Enum.CameraType.Custom
    UserInputService.MouseBehavior = Enum.MouseBehavior.Default
    UserInputService.MouseIconEnabled = true
    Connection.InputChanged:Disconnect(...)
    Connection.SetCamera:Disconnect(...)
  end

--[--]--[--]--
--[--]--[--]--

  Player.Self.CharacterAdded:Connect(function(...)
    Core:Disable(...)
  end)

--[--]--[--]--
--[--]--[--]--

  return Core

OTS.lua (4.7 KB)

Raycast behind the camera and if it hits subtract the distance.