I like this old school and simple to use cutscene edtior plugin.
[Fixed Again!] Cutscene Editor - Creator Marketplace (roblox.com
So I looked at the code and applied some methods to improve its performance and usability!
All the changes were made to this executable to use this replace the cutscene script with this here and it will make the cutscene loop forward and reverse cache its results for faster execution and you can apply the cutscene to a position.
To do this you record your cutscene at position 0,0,0 and then input your new subject and the script will offset the CFrame so you can make reusable cutscenes!
--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.
--Due to Caching do not use on a moving object
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,0,-8000)
local function cacheFrames(c1, f1, time, fov, roll) --Create Cache of frames for this keypoint
--local vx,vy,vz,C0,C1,C2,c3,c4,c5,c6,c7,c8 = c1:components() --Get all pieces of CFrame
--local c1=CFrame.new(vx,vy,vz,C0,C1,C2,c3,c4,c5,c6,c7,c8)--Redundant code to illustrate
local c1 = CFrame.new(c1.Position + ORI.Position, c1.LookVector + ORI.LookVector)-- Adding the offset position and their lookvector to get the new transformation.
--local vx,vy,vz,C0,C1,C2,c3,c4,c5,c6,c7,c8 = f1:components()--Field of view components
--local f1=CFrame.new(vx,vy,vz,C0,C1,C2,c3,c4,c5,c6,c7,c8)--redundant code to illustrate
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 -- CFrame,Focus point, Field of view
for i = 1,frames do --Do calculations for this frame
preload[i]= {CameraType = "Scriptable",--Set to scriptable so can modify camera free of character
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--if not calculated calculate cache
local prel= cacheFrames(c1, f1, time, fov, roll)--Get Frame calculations for the cutscene
totalcache[v]=prel --write the data to the global cache
end
--print(totalcache[v][3].roll)--print 3rd point CFrame
local frames=totalcache[v][1].frames
for i = 1,frames do -- unpack the cache for these frames
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()--Render Step wait
if Enabler==false then
break --Unused global variable to disable cutscene under specified conditions
end
end
end
tweenCam(CFrame.new(unpack(data[1].c1)),CFrame.new(unpack(data[1].f1)), data[1].step, data[1].FOV, data[1].Roll,3,false)--Start at the 1st keypoint
while Enabler do -- While the Enabler bool do
for i = 1,#data do--Forward cutscene
if Enabler==false then
break --break if enabler is false
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--Start at end of data
for v = 1,#data do --Reverse Cutscene
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
--Loop is over so revert back to player subject
c.CameraType = "Custom"
c.CameraSubject=game.Players.LocalPlayer.Character.Humanoid