How can I improve this cutscene module

Hello! I am trying to make an object-oriented cutscene module. This cutscene module, as the name implies, creates cutscenes. I want to have a cutscene base, and from that base I can create different types of cutscenes. Sadly, my code is not capable of that. I have considered making a base for my cutscenes, but it just made it more complicated.

I want my code to be easily usable, and I want to be able to add different types of cutscenes with different features without changing the code completely every time. Any help is appreciated!

Here is the cutscene module:

local TweenService = game:GetService("TweenService")
local rep = game:GetService("ReplicatedStorage")
local contentProvider = game:GetService("ContentProvider")
local players = game:GetService("Players")
local plr = players.LocalPlayer
local camera = workspace.CurrentCamera
local cutscene = {}

cutscene.__index = cutscene

function cutscene.new(model, target, cameraPos, waitTime, targetType, tweenArgs)
	local newcutscene = {}
	setmetatable(newcutscene, cutscene)

	if targetType == "Character" then

		newcutscene.target = target
		newcutscene.rootPart = target.PrimaryPart

		newcutscene.cameraScenes = {
			InitialOffset = CFrame.new(0.255599976, 5.66917801, -38.7787933, -0.999975026, -0.00107017357, 0.00699234521, -0, 0.988489866, 0.15128766, -0.00707376609, 0.151283875, -0.988465071),
			EndOffset = CFrame.new(-0.034362793, 1.76126051, -4.09686279, -1, -1.10869232e-05, 8.77379716e-05, 9.09494702e-13, 0.992110491, 0.125367075, -8.84356923e-05, 0.125367075, -0.992110491),
			TweenInformation = TweenInfo.new(7, Enum.EasingStyle.Cubic, Enum.EasingDirection.InOut),
			-- -0.0341682434, 2.04333591, -6.32910156, -1, -1.10869232e-05, 8.77379716e-05, 9.09494702e-13, 0.992110491, 0.125367075, -8.84356923e-05, 0.125367075, -0.992110491
			TimeDelay = waitTime
		}
	else

		newcutscene.model = model
		newcutscene.target = target
		newcutscene.cameraPos = cameraPos

		if (not tweenArgs) then 
			newcutscene.cameraScenes = {
				TimeDelay = waitTime,
			}
		else
			newcutscene.cameraScenes = {
				TimeDelay = waitTime,
				InitialOffset = tweenArgs[1],
				TweenInformation = TweenInfo.new(7, Enum.EasingStyle.Cubic, Enum.EasingDirection.InOut),
				EndOffset = tweenArgs[2]
			}
		end
	end

	return newcutscene
end

function cutscene:Initialize(targetType)
	if targetType == "Character" then
		local anim = Instance.new("Animation")
		local controller = self.target.Humanoid
		local initialCameraFrame = self.rootPart.CFrame:ToObjectSpace(camera.CFrame)
		local initialCameraType = camera.CameraType
		camera.CameraType = Enum.CameraType.Scriptable
		anim.AnimationId = "http://www.roblox.com/asset/?id=507770239"

		camera.CFrame = self.rootPart.CFrame:ToWorldSpace(self.cameraScenes.InitialOffset)

		local cameraTween = TweenService:Create(camera, self.cameraScenes.TweenInformation, {CFrame = self.rootPart.CFrame:ToWorldSpace(self.cameraScenes.EndOffset)})
		cameraTween:Play()
		self:StopAnimations()
		controller:LoadAnimation(anim):Play()

		cameraTween.Completed:Wait()
		cameraTween:Destroy()

		task.wait(self.cameraScenes.TimeDelay)

		camera.CFrame = self.rootPart.CFrame:ToWorldSpace(initialCameraFrame)
		camera.CameraType = initialCameraType
	elseif targetType == "Loading" then
		local pos = self.cameraPos.Position
		local lookAt = self.target.Position
		local cameraCFrame = CFrame.new(pos, lookAt)
		camera.CameraType = Enum.CameraType.Scriptable

		camera.CFrame = cameraCFrame

		self:LoadingAssets()
		task.wait(self.cameraScenes.TimeDelay)
		camera.CameraType = Enum.CameraType.Custom
	elseif targetType == "Tv" then
		print(self.cameraPos)
		print(self.target)

		local initialCameraFrame = self.target.CFrame:ToObjectSpace(camera.CFrame)
		local initialCameraType = camera.CameraType
		camera.CameraType = Enum.CameraType.Scriptable

		print(self.cameraScenes.InitialOffset)
		camera.CFrame = self.target.CFrame:ToWorldSpace(self.cameraScenes.InitialOffset)

		local cameraTween = TweenService:Create(camera, self.cameraScenes.TweenInformation, {CFrame = self.target.CFrame:ToWorldSpace(self.cameraScenes.EndOffset)})
		cameraTween:Play()

		cameraTween.Completed:Wait()
		cameraTween:Destroy()

		task.wait(self.cameraScenes.TimeDelay)

		camera.CFrame = self.target.CFrame:ToWorldSpace(initialCameraFrame)
		camera.CameraType = initialCameraType
	end
end

function cutscene:LoadingAssets()
	local minimumLoadedPlayers = #players:GetPlayers()
	local loadedPlayers = rep.loaded
	print(self.model)
	local loadingFrame = self.model.Sky.SurfaceGui.Frame
	local loadingNumberText = loadingFrame.loadingNumberText

	loadedPlayers.Changed:Connect(function()
		print("Im here")
		loadingNumberText.Text = loadedPlayers.Value .. "/" .. minimumLoadedPlayers
	end)
end

function cutscene:StopAnimations()
	local humanoid = self.target.Humanoid
	local animator = humanoid:FindFirstChildOfClass("Animator")
	for i,v in ipairs(animator:GetPlayingAnimationTracks()) do
		v:Stop()
	end
end

return cutscene

rbxl file:
CutSceneModule.rbxl (42.9 KB)

1 Like

Firstly Hello!

I hope you are well, today will bring many blessings!

I’ve seen this and similar resources, I don’t know how you feel about forking API.

But if you’re happy to use them!

There is a lot of resources, from highly competent programmers that could immensely boost work flow and save you time.

Some may even have the features you want, be open-sourced and allow you to reverse engineer the how’s and why it works rather than just using it for your own or just go ahead and use it for your own!

I have linked them here, I researched them prior to creating a similar thing for myself.

Hopefully they are helpful!

2 Likes