Dynamic fixed camera angles

You can write your topic however you want, but you need to answer these questions:
I’m trying to make a system that switches to the closest camera point for a stealth game that is played through security cameras.

my problem is that the code switches between camera angles instantly, leading to awkward movement. I’ve tried using a simple debounce, but this just breaks it.

here is my camera controler

local camera = game.Workspace.CurrentCamera
local cameraParts = game.Workspace:WaitForChild("CameraParts")
local Player = game.Players.LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
local HumanoidRootPart = Character:WaitForChild("HumanoidRootPart")

game:GetService("RunService").RenderStepped:Connect(function()
	local closestCameraPart = nil
	local shortestDistance = math.huge

	for i, v in cameraParts:GetChildren() do
		local distance = (HumanoidRootPart.Position - v.Position).magnitude
		if distance < shortestDistance then
			shortestDistance = distance
			closestCameraPart = v
		end
	end

	if closestCameraPart then
		camera.CFrame = CFrame.new(closestCameraPart.Position, HumanoidRootPart.Position)
	end
end)

any help is greatly appreciated!

2 Likes

You can interpolate the camera’s position and rotation over time using Lerp (linear interpolation) or TweenService .

local camera = game.Workspace.CurrentCamera
local cameraParts = game.Workspace:WaitForChild("CameraParts")
local Player = game.Players.LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
local HumanoidRootPart = Character:WaitForChild("HumanoidRootPart")
local TweenService = game:GetService("TweenService")

local currentCameraPart = nil
local tweenInfo = TweenInfo.new(1, Enum.EasingStyle.Quad, Enum.EasingDirection.Out) -- Adjust duration and easing as needed

local function switchToCameraPart(cameraPart)
    if cameraPart == currentCameraPart then return end -- Skip if already on this camera
    currentCameraPart = cameraPart

    local goal = {}
    goal.CFrame = CFrame.new(cameraPart.Position, HumanoidRootPart.Position)
    local tween = TweenService:Create(camera, tweenInfo, goal)
    tween:Play()
end

game:GetService("RunService").RenderStepped:Connect(function()
    local closestCameraPart = nil
    local shortestDistance = math.huge

    for _, v in pairs(cameraParts:GetChildren()) do
        local distance = (HumanoidRootPart.Position - v.Position).magnitude
        if distance < shortestDistance then
            shortestDistance = distance
            closestCameraPart = v
        end
    end

    if closestCameraPart then
        switchToCameraPart(closestCameraPart)
    end
end)

this unfortunately doesn’t work, and it just switches back to the default roblox camera after the lerp.

nevermind, i modified your code and removed the camera module that roblox uses to fix it. here’s the code

local camera = game.Workspace.CurrentCamera
local cameraParts = game.Workspace:WaitForChild("CameraParts")
local Player = game.Players.LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
local HumanoidRootPart = Character:WaitForChild("HumanoidRootPart")
local TweenService = game:GetService("TweenService")
local currentCameraPart = nil
local tweenInfo = TweenInfo.new(1, Enum.EasingStyle.Quad, Enum.EasingDirection.Out) -- Adjust duration and easing as needed
local debounce = false

local function switchToCameraPart(cameraPart)
	if cameraPart == currentCameraPart then
		camera.CFrame = CFrame.new(cameraPart.Position, HumanoidRootPart.Position)
	end
	if debounce == false then
    	currentCameraPart = cameraPart   	
		camera.CFrame = CFrame.new(cameraPart.Position, HumanoidRootPart.Position)
		debounce = true
		wait(0.25)
		debounce = false
	end
    --local tween = TweenService:Create(camera, tweenInfo, goal)
    --tween:Play()
end

game:GetService("RunService").RenderStepped:Connect(function()
    local closestCameraPart = nil
    local shortestDistance = math.huge

    for _, v in pairs(cameraParts:GetChildren()) do
        local distance = (HumanoidRootPart.Position - v.Position).magnitude
        if distance < shortestDistance then
            shortestDistance = distance
            closestCameraPart = v
        end
    end

    if closestCameraPart then
        switchToCameraPart(closestCameraPart)
    end
end)

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