I’ve always loved the old school Cutscene script made by CloneTrooper1019. You can get a copy of his fixed plugin for free on the marketplace as it has been a mainstay of the community for a long time.
So I improved its efficientcy by adding a frame buffer.This caches the result of the entire array of calculations into the beginning of the point transition. Then the results are indexed into the total cache and then the total cache is executed forward and reverse with no calculation overhead just looping through a cached table.
local HttpService = game:GetService("HttpService")
local data = HttpService:JSONDecode(script.CutsceneData.Value)
local c = game.Workspace.CurrentCamera
local rs = game:GetService("RunService").RenderStepped
local function cacheFrames(c1, f1, time, fov, roll)
local preload={}
local c0,f0,fv0,r0,frames = c.CoordinateFrame,c.Focus,c.FieldOfView,c:GetRoll(),time/0.015
for i = 1,frames do
preload[i]=
{CameraType = "Scriptable",
CoordinateFrame = CFrame.new(c0.p:lerp(c1.p,i/frames),f0.p:lerp(f1.p,i/frames)),
FieldOfView = (fv0+(fov-fv0)*(i*(1/frames))),
roll=r0+(roll-r0)*(i*(1/frames)),
frames=frames}
-- rs:wait()
end
return preload
end
local totalcache={}
local prel=nil
function tweenCam(c1, f1, time, fov, roll,v)
if totalcache[v]==nil then
local prel= cacheFrames(c1, f1, time, fov, roll)--totalcache[v]
totalcache[v]=prel
end
local frames=totalcache[v][1].frames
for i = 1,frames do
c.CameraType = totalcache[v][i].CameraType
c.CoordinateFrame = totalcache[v][i].CoordinateFrame--:ToWorldSpace(CFrame.new(preload[i].CoordinateFrame.Position+primary.Position))
c.FieldOfView = totalcache[v][i].FieldOfView
c:SetRoll(totalcache[v][i].roll)
task.wait()
if Enabler==false then
break
end
end
end
Enabler=true--change to turn off
--initial frame to start at
--tweenCam(CFrame.new(unpack(data[3].c1)),CFrame.new(unpack(data[3].f1)), data[3].step, data[3].FOV, data[3].Roll,0,false)--cache as frame zero.
while Enabler do
for i = 1,#data do
if Enabler==false then
break
end
tweenCam(CFrame.new(unpack(data[i].c1)),CFrame.new(unpack(data[i].f1)), data[i].step, data[i].FOV, data[i].Roll,i,false)
end
local i=#data
for v = 1,#data do
i=i-1
if Enabler==false then
break
end
if i>1 then
tweenCam(CFrame.new(unpack(data[i].c1)),CFrame.new(unpack(data[i].f1)), data[i].step, data[i].FOV, data[i].Roll,-i,false)
end
end
end
c.CameraType = "Custom"
c.CameraSubject=game.Players.LocalPlayer.Character.Humanoid
[Fixed Again!] Cutscene Editor - Creator Marketplace (roblox.com)
https://devforum.roblox.com/t/optimization-on-the-roblox-client/2667763/9
You owuld use this script in place of the executable that this plugin provide when you generate a onplayerentered script. Which generates a onplayer entered server script object and client cutscene script. This is the code for the local cutscene. You will notice more consistent performance across all devices with this code. I may make an updated version of this plugin in the future but after reviewing its code it’s pretty monotonous. So I would only make minor updates but something I would like to do is export the cutscene object so you can reposition the cutscene and execute the cutscene offset from a primary part.
Next this is the final version of the code! This version offsets the entire cutscene be a position so you would record you cutscnee at position 0,0,0 and then it back back on a specific area! Allowing you to reuse your cutscenes anywhere in your game.
--instructions--
--optimized by Magus_ArtStudios with a cache frame function.
--Save the results of the math in memory rather than excute it every frame
--if moving point do not use global cache.
--Does not work well with moving point until updated.
local HttpService = game:GetService("HttpService")
local data = HttpService:JSONDecode(script.CutsceneData.Value)
local c = game.Workspace.CurrentCamera
local rs = game:GetService("RunService").RenderStepped
local totalcache={}
local prel=nil
local Enabler=true--change to turn off
local ORI=CFrame.new(-8000, 3322, -8000)
local function cacheFrames(c1, f1, time, fov, roll)
local c1 = CFrame.new(c1.Position + ORI.Position, c1.LookVector + ORI.LookVector)
local f1 = CFrame.new(f1.Position + ORI.Position, f1.LookVector + ORI.LookVector)
local preload={}
local c0,f0,fv0,r0,frames = c.CoordinateFrame,c.Focus,c.FieldOfView,c:GetRoll(),time/0.015
for i = 1,frames do
preload[i]=
{CameraType = "Scriptable",
CoordinateFrame = CFrame.new(c0.p:lerp (c1.p,i/frames),f0.p:lerp(f1.p,i/frames)),
FieldOfView = (fv0+(fov-fv0)*(i*(1/frames))),
roll=r0+(roll-r0)*(i*(1/frames)),
frames=frames}
end
return preload
end
local goalfps=1/70
function tweenCam(c1, f1, time, fov, roll,v,reverse)
--if totalcache[v]==nil then
local prel= cacheFrames(c1, f1, time, fov, roll)
totalcache[v]=prel
--end
--print(totalcache[v][3].roll)
local frames=totalcache[v][1].frames
for i = 1,frames do
c.CameraType = totalcache[v][i].CameraType
c.CoordinateFrame = totalcache[v][i].CoordinateFrame
c.FieldOfView = totalcache[v][i].FieldOfView
c:SetRoll(totalcache[v][i].roll)
rs:Wait()
if Enabler==false then
break
end
end
end
tweenCam(CFrame.new(unpack(data[3].c1)),CFrame.new(unpack(data[3].f1)), data[3].step, data[3].FOV, data[3].Roll,3,false)
while Enabler do
for i = 1,#data do
if Enabler==false then
break
end
tweenCam(CFrame.new(unpack(data[i].c1)),CFrame.new(unpack(data[i].f1)), data[i].step, data[i].FOV, data[i].Roll,i,false)
end
local i=#data
for v = 1,#data do
i=i-1
if Enabler==false then
break
end
if i>1 then
tweenCam(CFrame.new(unpack(data[i].c1)),CFrame.new(unpack(data[i].f1)), data[i].step, data[i].FOV, data[i].Roll,-i,false)
end
end
end
c.CameraType = "Custom"
c.CameraSubject=game.Players.LocalPlayer.Character.Humanoid