What is the best way to smoothly transition into a regular camera mode?

I need to transition a player’s camera into a cutscene then back to where their camera originally was.
Currently how I do this is by saving the CFrame of the players camera, changing into to scriptable then tweening it to the cutscene part. After the cutscene I then tween the camera back to the CFrame I saved from before I modified the camera then change it back to the camera mode it was at.

This works if the player hasn’t moved at all but now I need to do this for a cutscene where the player is teleported. I decided to do this by briefly changing the players camera to classic, saving the CFrame then changing it back to Scriptable and tween it there. This works but some players can just barely see their screen flash and find it pretty annoying.

Is there any way to calculate the CFrame the camera will move to with the classic camera mode before actually setting the camera to classic? I assume this isn’t possible without rewriting the entire camera script but it’s worth asking.

As a last result I can just make the screen fade to black and then just change the camera mode but I’d prefer it if I can tween the camera.

5 Likes

You can accomplish this with :ToObjectSpace(). Here is an example :

local contextAction = game:GetService("ContextActionService")
local TweenService = game:GetService("TweenService")

local Camera = workspace.CurrentCamera
local Character = script.Parent
local Head = Character:WaitForChild("Head")

local savedCF = nil

local function saveCFrame(action, inputState)
	if inputState ~= Enum.UserInputState.Begin then return end
	savedCF = Head.CFrame:ToObjectSpace(Camera.CFrame) -- Save the CFrame relative to the character's head. (offset)
end

local function loadCFrame(action, inputState)
	if inputState ~= Enum.UserInputState.Begin then return end
	if savedCF then
		local originalCF = Head.CFrame * savedCF -- Multiply heads cframe by our saved cframe.
		
		TweenService:Create(Camera, TweenInfo.new(1, Enum.EasingStyle.Quad), {CFrame = originalCF}):Play()
	end
end

contextAction:BindAction("SaveCF", saveCFrame, false, Enum.KeyCode.Q) -- bind save cframe
contextAction:BindAction("LoadCF", loadCFrame, false, Enum.KeyCode.E) -- load saved cframe
4 Likes

Thanks, this works really well.
Only thing I changed is to use something more static (like the HumanoidRootPart) rather than the head since the head can move a bunch during the R15 idle animation or an emote which can mess you up if you save while it is rotated.

1 Like

Personally I feel like TweenService is better