Camera Bind: bind the camera to a part and update it constantly!

This module binds the player’s camera to a part and constantly updates it via RunService.
This module must be run in a local script.


Model: https://create.roblox.com/store/asset/16212469197
Showcase: showcase.rbxl (47.3 KB)
Documentation: Camera Bind Documentation


Code if you don’t want to open it in Roblox Studio:

--!native

local CameraModule = {}
local CurrentCamera = workspace.CurrentCamera
local plr = game.Players.LocalPlayer
local RunService = game:GetService("RunService")
local Connection


if not RunService:IsClient() then
	error("Module must be required on client.", 2)
end

local function TweenCam(target)
	local ts = game:GetService("TweenService")
	local ti = TweenInfo.new(0.5, Enum.EasingStyle.Sine, Enum.EasingDirection.Out)
	local tg = {CFrame = target.CFrame}
	local tc = ts:Create(CurrentCamera, ti, tg)
	tc:Play()
	tc.Completed:Wait()
end

local function Bind(target, performance)

	CurrentCamera.CameraType = Enum.CameraType.Scriptable


	if performance == false then
		Connection = RunService.RenderStepped:Connect(function()
			CurrentCamera.CFrame = target.CFrame
		end)

	else

		Connection = RunService.Heartbeat:Connect(function()
			CurrentCamera.CFrame = target.CFrame
		end)
	end
end

function CameraModule:BindCamera(Target: Part, Performance: boolean?, Tween: boolean?)

	if typeof(Target) ~= "Instance" and not Target:IsA("Part") then error(`BindCamera expects Target to be a Part, got {tostring(Target)}`, 2) end
	if typeof(Performance) ~= "boolean" then Performance = false end
	if typeof(Tween) ~= "boolean" then Tween = false end

	if Connection then
		Connection:Disconnect()
		Connection = nil
	end
	if not Tween then
		CurrentCamera.CFrame = Target.CFrame
	else
		TweenCam(Target)
	end
	Bind(Target, Performance)
end

function CameraModule:SetCameraToPart(Target: Part, Tween: boolean?)

	if typeof(Target) ~= "Instance" and not Target:IsA("Part") then error(`SetCameraToPart expects Target to be a Part, got {tostring(Target)}`, 2) end
	if typeof(Tween) ~= "boolean" then Tween = false end

	if Connection then
		Connection:Disconnect()
		Connection = nil
	end
	CurrentCamera.CameraType = Enum.CameraType.Scriptable
	if not Tween then
		CurrentCamera.CFrame = Target.CFrame
	else
		TweenCam(Target)
	end
end

function CameraModule:Unbind()
	if Connection then
		Connection:Disconnect()
		Connection = nil
	end

	CurrentCamera.CameraSubject = plr.Character.Humanoid
	CurrentCamera.CFrame = plr.Character.Head.CFrame
	CurrentCamera.CameraType = Enum.CameraType.Custom
end

return CameraModule
4 Likes

Uhh, not trying to be annoying but, why not just do this?

local part = ...

-- When you want to bind
local connection = game:GetService("RunService").RenderStepped:Connect(function()
  workspace.CurrentCamera.CFrame = part.CFrame
end)

-- When you want to unbind
connection:Disconnect()
3 Likes

Hi,

Do you have an .rbxl, of it and perhaps a part that moves? Could this be used to make cutscenes?

Thanks

2 Likes

It can be used to make cutscenes!!! You can also rig it to a humanoid and animate the camera easily.

I’ll give an rbxl file in a bit, with the same rotating part I tested the module with.

1 Like

Well if you want to make your own script you can, but I made this module to save people’s time.

2 Likes

That’s not really what I meant, it’s kinda pointless to make a module just for this. No hate though.

2 Likes

No it isn’t?? The entire point of modules is to not to have 50 billion scripts doing the same thing. I just shared a module I made publicly

1 Like

i have attached a showcase to my original post now!

1 Like

nice! Now I am dizzy!
thanks for sharing the .rbxl

2 Likes

i have added documentation!

Have fun!

1 Like

Update: removed the tables as they were useless and replaced them with a non-shared global variable and changed run service’s variable.

1 Like

UPDATE:
Added a new function, SetCameraToPart (read more here: Camera Bind Documentation)
Fixed Unbind not working due to accidentally using a local variable for Connection.

1 Like

UPDATE!!! I added a new argument, Tween. learn more here:

ANOTHER UPDATE: i just realized i forgot to check for tween for BindCamera which meant it’d get tweened regardless if it was true or now. whoops.