What is the simplest way to fix 3rd person camera clipping?

Not so long ago I tried making a over shoulder camera that is partly inspired by console games.

Here’s how it looks


I ran into an issue that the camera is now clipping through the walls so I tried fixing that, although I think I did the whole Raycast logic wrong, it stopped clipping but just behaves weirdly.

Here is the code of the camera:

local Camera = workspace.CurrentCamera
local uis = game:GetService("UserInputService")
local Players = game:GetService("Players")
local Plr = Players.LocalPlayer
local Char = Plr.Character or Plr.CharacterAdded:Wait()
local humanoid = Char:WaitForChild("Humanoid")
local HRP = Char:WaitForChild("HumanoidRootPart")
local RS = game:GetService("RunService")

humanoid:SetStateEnabled(Enum.HumanoidStateType.Jumping, false)

local isZooming = false


local context = game:GetService("ContextActionService")

Camera.CameraType = Enum.CameraType.Scriptable



-- Values

local xAngle = 0
local yAngle = 0
local cameraPos = Vector3.new(2,-0.3,6)

context:BindAction("CameraMovement", function(_,_,input)
	xAngle = xAngle - input.Delta.x*0.4
	yAngle = math.clamp(yAngle - input.Delta.y*0.4,-80,80) --0.4,-80,80
end, false, Enum.UserInputType.MouseMovement)


uis.InputBegan:Connect(function(input, chat)
	if chat then return end 

	if input.KeyCode == Enum.KeyCode.LeftShift then 
		isZooming = true
	end

end)

uis.InputEnded:Connect(function(input, chat) 
	if chat then return end 

	if input.KeyCode == Enum.KeyCode.LeftShift then 
		isZooming = false
	end



end)


RS.RenderStepped:Connect(function()
	if Char and HRP then

		if isZooming == true then
			cameraPos = Vector3.new(2,-0.3,3)
		else
			cameraPos = Vector3.new(2,-0.3,6)
		end


		local startCFrame = CFrame.new((HRP.CFrame.p + Vector3.new(0,2,0)))*CFrame.Angles(0, math.rad(xAngle), 0)*CFrame.Angles(math.rad(yAngle), 0, 0)

		local rightTiltAngle = math.rad(5)  -- this rotates
		local downTiltAngle = math.rad(5) 
		local tiltedCameraPos = CFrame.Angles(0, rightTiltAngle, 0):VectorToWorldSpace(cameraPos)
		local cameraCFrame = startCFrame + startCFrame:VectorToWorldSpace(tiltedCameraPos)
		local finalCframe 
		
		--WELCOME TO THE MIND FUGDE
		local rParams = RaycastParams.new()
		rParams.FilterType = Enum.RaycastFilterType.Exclude
		rParams.FilterDescendantsInstances = {Char}
		
		local origin = cameraCFrame.Position --should be cam pos -- fix here
		local direction = cameraCFrame.Position - HRP.Position --Vector3.new(0.5,0.5,0.5)
		local raycastResult = workspace:Raycast(origin,direction,rParams)
		
		
		
		if raycastResult then
			print("IM HIITING STUFF HOW QUEER")
			finalCframe = raycastResult.Position + raycastResult.Normal * 0.2	 
			print("were fine")
			finalCframe = cameraCFrame.p
		end
			

		local cameraFocus = startCFrame + startCFrame:VectorToWorldSpace(Vector3.new(cameraPos.X,cameraPos.Y,-50000))

		Camera.CFrame = Camera.CFrame:Lerp(CFrame.new(finalCframe,cameraFocus.p), 0.3) --cameraCFrame.p
	end
end)

I would be happy with any response, I really do not know how to approach this sort of issue I’ve been scrolling for hours to find a solution.
Thank you in advance

Please ignore the prints I’m referencing the “I guess we doin circles now” meme

The origin should be the whatever the camera is pointing at (startCFrame.Position?) and the direction should be the negative of the vector pointing from the camera’s position to whatever it is pointing at.
Diagram:
image

1 Like

Thank you for your response. I tried that method out and played around with the values I could set for origin. It complely removed the issues I had with clipping! Although the camera is kind of glued itself to the wall, i’ll play around with this more

Oh this works somewhat decently, I only replaced origin with startCFrame.Position instead of cameraCFrame.Position @Pokemoncraft5290 THANK YOU!!

1 Like