Smooth Moving Camera Cutscene

Hello there! I was trying to figure out how to get the smooth moving camera effect like in this video:

Any help would be appreciated ty!

1 Like

you can use tween or you can attract a camera to a brick then animate it

I looked at the video and I think I could replicate that using sine functions along with CFraming.
You could also accomplish the same thing using the Sine EasingStyle with TweenService.

1 Like

oh wow, Do you mind telling me what should I use all I have in my right now is like adding multiple parts :worried: but I don’t know if its effective

The basic idea is that you use TweenService and set it’s easing style and easing direction so that it acts like a sine respecting the focus CFrame.

EasingDirection
TweenInfo.new
EasingStyle
TS:Create
Tween

local cam = workspace.CurrentCamera -- the player's point of view
local TS = game:GetService("TweenService") -- tween service
-- lets create an array of positions relative to the origin.
-- Assume left is -X, right is +X, up is +Y, down is -Y, forward is -Z, and backwards is +Z. 
local positions = {Vector3.new(-1, 0, -1), Vector3.new(1, 1, 1), Vector3.new(-1, -1, 0.8), Vector3.new(1, 0, -1)}
local timeToPos = {0.1, 0.75, 0.25, 0.75} -- seconds to get to the positions
local originCF = cam.CFrame -- you would change this to focus the thing you are looking at.

cam.CameraType = Enum.CameraType.Scriptable
for i=1,positions,1 do -- loop through the positions
  local info = TweenInfo.new(timeToPos[i], Enum.EasingStyle.Sine, Enum.EasingDirection.Out)
  local Tween = TS:Create(cam, info, {
    CFrame = originCF*CFrame.new(positions[i])
  })
  Tween:Play()
  Tween.Completed:Wait() -- yeilds until tween finishes
end
wait(1)
cam.CameraType = Enum.CameraType.Fixed

I’m sorry I have not tested this code so if it doesn’t work or there’s a mistake I’m sorry.

1 Like

thank you! I’ll test it right now


there is a script error I found

maybe replace positions with the #positions

local cam = workspace.CurrentCamera -- the player's point of view
local TS = game:GetService("TweenService") -- tween service
-- lets create an array of positions relative to the origin.
-- Assume left is -X, right is +X, up is +Y, down is -Y, forward is -Z, and backwards is +Z. 
local positions = {Vector3.new(-1, 0, -1), Vector3.new(1, 1, 1), Vector3.new(-1, -1, 0.8), Vector3.new(1, 0, -1)}
local timeToPos = {0.1, 0.75, 0.75, 0.75} -- seconds to get to the positions
local originCF = cam.CFrame -- you would change this to focus the thing you are looking at.

cam.CameraType = Enum.CameraType.Scriptable
cam.CFrame = originCF*CFrame.new(positions[1])
for i=1,#positions,1 do -- loop through the positions
  local info = TweenInfo.new(timeToPos[i], Enum.EasingStyle.Sine, Enum.EasingDirection.InOut)
  local Tween = TS:Create(cam, info, {
    CFrame = originCF*CFrame.new(positions[i])
  })
  Tween:Play()
  Tween.Completed:Wait() -- yeilds until tween finishes
end
wait(1)
cam.CameraType = Enum.CameraType.Fixed

Try this

This code uses Enum.EasingDirection.InOut instead of Enum.EasingDirection.Out


it works but why it’s like this

like the cutscene is kinda weird??

run it in command line


1 Like

omg it works in command line but how do I make it loop and stop the loop when the animation is done?

There’s a few different ways to do this.
You could make up several other positions and time values to make the animation run longer.

Or you could even utilize the math.random() function.

For example you could use math.random()*2 - 1 which will give a number between -1 and 1 and use that inside of Vector3.new() instead of the predefined values. You could let this loop go on for however long you want.

Here is a function that will do it for a set amount of time using the random function.

local cam = workspace.CurrentCamera -- the player's point of view
local TS = game:GetService("TweenService") -- tween service
-- lets create an array of positions relative to the origin.
-- Assume left is -X, right is +X, up is +Y, down is -Y, forward is -Z, and backwards is +Z.
local function doCamShake(originCF, lengthOfTime)
	cam.CameraType = Enum.CameraType.Scriptable
	cam.CFrame = originCF
	local currentTime = 0
	while currentTime < lengthOfTime do -- loop through the positions
		local xtime = math.random()*0.9+0.1
		if currentTime+xtime > lengthOfTime then
			xtime = lengthOfTime - currentTime + 0.01
		end
		currentTime = currentTime + xtime
		local info = TweenInfo.new(math.random()*0.9+0.1, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut)
		local Tween = TS:Create(cam, info, {
			CFrame = originCF*CFrame.new(math.random()*2-1, math.random()*2-1, math.random()*2-1)
		})
		Tween:Play()
		Tween.Completed:Wait() -- yeilds until tween finishes
	end
	wait(1)
	cam.CameraType = Enum.CameraType.Fixed
end
doCamShake(cam.CFrame, 5) -- random shaking for 5 seconds at the current CFrame

[EDITED] sorry first post was wrong.

1 Like

I tried it and it worked thank you so much for helping me!

To better answer this question, on the line where I wrote:

You can add more Vector3.new(x,y,z) and corresponding time length values to the tables to make the camera animation run longer.