Hey all, I’ve been scratching my head at this for the past week or so. I have a custom camera system with shiftlock, and I don’t want players sticking their camera into walls. I’ve tried about half a dozen reworks already but all of them feel weird when going near a wall.
After a further 3 days of experimenting, this is the best I’ve gotten it feeling yet.
Here is the code for those struggling with the same issue:
local function wallCast(origin, target)
local magnitude = (origin.Position - endPoint.Position).Magnitude
local originalMagnitude = magnitude
local ray = Ray.new(origin.Position, endPoint.Position - origin.Position).Unit
for i = -0.2, 0.2, 0.4 do
for i2 = -0.2, 0.2, 0.4 do
local multiply = originalMagnitude / magnitude
local targetPosition = (endPoint * CFrame.new(i * multiply, i2 * multiply, 0)).Position - origin.Position
local result = workSpace:Raycast(origin.Position, targetPosition, cameraRaycastParams)
if result then
local closestPoint = ray:ClosestPoint(result.Position)
local newMagnitude = (origin.Position - closestPoint--[[result.Position]]).Magnitude -- +/- 0.2?
if newMagnitude < magnitude then
magnitude = newMagnitude
end
end
end
end
local alpha = magnitude / originalMagnitude
return alpha
end
-- cameraOffset is Vector3.new(1.5, 0, 0) if shiftlocking
local zoomValue = zoom.Value-- CFrame value with Z set at zoom level
local origin =-- CFrame.new(subject.Position) + rotation
local target, alpha
if cameraOffset ~= Vector3.new(0, 0, 0) then
local offsetOrigin = origin * CFrame.new(cameraOffset)
target = offsetOrigin * CFrame.new(0, 0, minimumZoomBaseValue - 0.01)
alpha = wallCast(origin, target)
if alpha == 1 then
origin = target
target = offsetOrigin * zoomValue
alpha = wallCast(origin, target)
end
else
target = origin * zoomValue
alpha = wallCast(origin, target)
end
camera.CFrame = origin:Lerp(target, alpha)
I think this is just gonna have to do. It’s not perfect, but I’m not smart enough to figure out a better solution.