Camera Collision Implementation

Hello! My camera runs into walls and goes straight through them. I tried making the cameraPart’s canCollide = true, but that only makes the camera go haywire and spin around in circles uncontrollably when it collides with objects.


So, here’s my custom camera:

local player = game.Players.LocalPlayer
local cam = workspace.CurrentCamera
local char = script.Parent
local hrp = char:WaitForChild("HumanoidRootPart")

cam.CameraType = Enum.CameraType.Scriptable
cam.Name = "PlayerCam"

local cameraPart = Instance.new("Part")
cameraPart.Name = "CameraPart"
cameraPart.Transparency = 1
cameraPart.CanCollide = false
cameraPart.Parent = workspace

cameraPart.CFrame = CFrame.new(hrp.Position + Vector3.new(0,zoomY,zoomZ), hrp.Position)
local bp = Instance.new("BodyPosition")
bp.MaxForce = Vector3.new(math.huge, math.huge, math.huge)
bp.Parent = cameraPart

game:GetService("RunService").RenderStepped:Connect(function()
	bp.Position = hrp.Position + Vector3.new(0,zoomY,zoomZ)
	cam.CFrame = cameraPart.CFrame + Vector3.new(0,0,0)
end)

Any help implementing collision so that the player can’t see straight through buildings would be great. Maybe the camera would get higher if it is within some distance of an object it would collide with. That kind of thing.

1 Like

Raycast from the player’s position to the camera’s position at the “desired” distance, and if anything gets hit move the camera to the hit point

3 Likes

I’ll try this out. Seems like a pretty straightforward system. Thanks for your input!

I never actually got a solution for this, so I’m coming back to revive my call for help lol. I did try the raycasting idea, but couldn’t get it to work correctly. It would shoot my camera 100 miles into the sky every time it collided with something, and the motion wasn’t even smooth.

Add a condition that compares the magnitude of the camera to avoid sending the camera far away. You can also use TweenService to have your camera move smoothly

If it’s still being launched, that could mean the camera collision is still turned on. Try turning it off again and maybe set a maximum distance for projecting the camera.

I was able to get this semi-working by making the camera zoom in a specified amount whenever the cameraPart is touching an obstacle. However, because it’s in constant contact with another object, the camera can get a bit jumpy and twitchy. This was without raycasts. Any better ideas or ways to smooth it out?

https://i.imgur.com/ST3X6zT.mp4

local bp = Instance.new("BodyPosition")
bp.MaxForce = Vector3.new(math.huge, math.huge, math.huge)
bp.Parent = cameraPart

game:GetService("RunService").RenderStepped:Connect(function()
	local Parts = cameraPart:GetTouchingParts()

	if #Parts == 0 then
		bp.Position = hrp.Position + Vector3.new(0,zoomY,zoomZ)
	else
		bp.Position = hrp.Position + Vector3.new(0,zoomY - 15,zoomZ + 15)
	end
	cam.CFrame = cameraPart.CFrame
end)

I did it! I implemented my own method to determine whether or not the next location of the camera will collide with an object. If it does, then I increment the zoom until it doesn’t. This works pretty well and avoids most, if not all, object collisions with the camera.

local testPart = Instance.new("Part")
local inc = 1

function checkCollision(part)
	local Parts = part:GetTouchingParts()
	if #Parts == 0 then
		bp.Position = part.Position
		inc = 1
	else
		part.Position = hrp.Position + Vector3.new(0,zoomY - inc,zoomZ + inc)
		inc += 1
		checkCollision(part)
	end
end

game:GetService("RunService").RenderStepped:Connect(function()
	
	-- move the test object first
	testPart.Transparency = 1
	testPart.CanCollide = false
	testPart.Position = hrp.Position + Vector3.new(0,zoomY,zoomZ)
	testPart.Parent = workspace
	
	-- check if touching, if so, move the bp to the part position
	checkCollision(testPart)
	
	cam.CFrame = cameraPart.CFrame
end)
4 Likes

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.