Tweening Multiple Camera Points

Hello! :grinning: :wave:

I’m currently trying to tween a cutscene that has multiple camera points in a map with the use of TweenService. It works sometimes, but here’s the problem:

When I test out the cutscene the first time, the camera only focuses on one camera point and not the rest of the camera points. After waiting a while, the cutscene script (which is a local script btw) finds the camera points in the map and runs normally.

Here’s what I did/scripted up until this point:

  • When players (split into 2 teams (runners and the killer)) are teleported inside a randomly selected map, the server fires a RemoteEvent through :FireClients() / :FireClient(), and it enables the map cutscene.

  • In the Client-Side of the game, the Cutscene script finds the camera points in the map (in Workspace, labeled “Point1”, “Point2”, etc) and adds them into a number/variable?? (idk the terminology, let’s just call it CameraList) so the camera can cycle through the points. All of this is inside a function and returns the CameraList so it can be used later on.

  • The cutscene script then grabs the CameraList from the previous function; sets the camera to “Scriptable” and to the first CameraPoint in the map, and cycles through all of the camera points in a for loop. I also threw in a pcall inside the for loop for debugging purposes (just in case if something goes wrong).

Here’s what I’ve attempted to solve the problem:

  • I’ve tried looking for existing points inside CameraParts (see “hierarchy of the CameraPoints” below) in a generic for ipairs loop using string.sub, string.match, etc…
    but the output keeps warning me this message (see “the output” below) .

Essentials

the output:

this doesn’t print out any errors, just a warning from the pcall function i did

Output

hierarchy of the CameraPoints:

Hierarchy

cutscene script:

--Services
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local TweenService = game:GetService("TweenService")
local Players = game:GetService("Players")

--RemoteEvents
local Network = ReplicatedStorage:WaitForChild("Network")
local RemoteEvents = Network:WaitForChild("RemoteEvents")
local MapCutscene = RemoteEvents:WaitForChild("MapCutscene")

--Variables
local tween
local CutsceneDuration = 8
local Camera = game:GetService("Workspace").CurrentCamera
local CurrentMap = game:GetService("Workspace").MapHandler:WaitForChild("CurrentMap", 500)
local CameraPoints = CurrentMap.Assets:WaitForChild("CameraParts")
local LocalPlayer = Players.LocalPlayer
local Character = LocalPlayer.Character or LocalPlayer.CharacterAdded:Wait()

--Functions

local function getCutscenePoints()
	local i = 0
	
	for x,y in ipairs(CameraPoints:GetChildren()) do
			if string.match(y.Name, "%d+") ~= nil then --If all of the points that start with "Point" followed by a number in numerical order  aren't nil then
				i = i + 1 
		     end
	end
	
	return i
end

--Events
MapCutscene.OnClientEvent:Connect(function(Mode)
	
	if type(Mode) == 'string' then
		if Mode == "Activate" then
			 
			Camera.CameraType = Enum.CameraType.Scriptable
			Camera.CFrame = CameraPoints:WaitForChild("Point1").CFrame
			
			local get = getCutscenePoints()
			print(get)
			
					for i = 1, get do
					print('a')
					local success, err = pcall(function()
						print('running')
						local inf = TweenInfo.new(CutsceneDuration, Enum.EasingStyle.Linear, Enum.EasingDirection.Out, 0, false, 0)
						local goal = {CFrame = CameraPoints["Point"..i + 1].CFrame}
						
						tween = TweenService:Create(Camera, inf, goal)
						tween:Play()
						
						wait(CutsceneDuration)
						
						tween:Cancel()
						
						Camera.CameraType = Enum.CameraType.Custom	
						Camera.CameraSubject = Character.Humanoid
					end)
					if not success then
						warn(err)
					end
				end
			end	
		end
end)

Thanks in advance.

1 Like

Use this is plugin https://www.roblox.com/library/142296237/Deprecated-Cutscene-Editor-Plugin

As much as I want to use that plugin, it’s deprecated and I want to try this on my own.

Oh okey im look at your script wait a minute

Look at this is video he learn a lerping https://www.youtube.com/watch?v=LdwNqyknyPU

I don’t feel like switching everything to lerping… I want to use TweenService, since it’s easy to use and flexible imo.

Yes, please stick with tweenservice. It’s much more customizeable and also easier to use. I would never recommend lerping the camera.

1 Like

Where exactly is CameraPoints defined?

I’ve been reading through the script but I don’t exactly know where to find that, and it seems it stems from the same kind of problem.

Also, why are you doing i + 1? Don’t you want 1-2-3-4? Right now, it’s 2-3-4-5,which is confusing me.

Where exactly is CameraPoints defined? I’ve been reading through the script but I don’t exactly know where to find that, and it seems it stems from the same kind of problem.

Oops… I forgot to post the beginning of the script, my apologies. I’ve updated the code in my original post, so you can see where CameraPoints is defined.

Also, why are you doing i + 1 ? Don’t you want 1-2-3-4? Right now, it’s 2-3-4-5,which is confusing me.

I do want it 1-2-3-4 (I thought I was doing just that), but it seems I ran into a tiny mistake. :man_facepalming:

Instead of doing wait(CutsceneDuration), try doing tween.Completed:Wait() and see if that works.

Commonly, this was the issue that kept on affecting my cutscenes, since it would kinda overlap.

wait(CutsceneDuration) won’t exactly wait that much seconds, causing it to might take longer for certain cutscenes to end, tween.Completed:Wait() waits exactly until the tween ends.

2 Likes

Ah, thinking of a language that wasn’t lua? Makes sense, lua’s strange. Index’s starting on 1 like what??

Anyway, I’d suggest using :WaitForChild() and defining the Point before actually setting the goal. The code can be viewed as so.

local pointText = "Point"..i
local point = CameraPoints:WaitForChild(pointText)

Also, why not just define goal as goal = CameraPoints["Point"..i + 1].CFrame?

I didn’t know you could do that… that’s pretty neat! Thanks for the suggestion. :grin:

1 Like

Ah, thinking of a language that wasn’t lua? Makes sense, lua’s strange. Index’s starting on 1 like what??

I’m learning Python this year, and I think some of the stuff I’ve learned is getting into my head… :joy: :joy:

Also, why not just define goal as goal = CameraPoints["Point"..i + 1].CFrame ?

I tried doing that, but the output only showed me this:

Dictionary

The reason I defined goal in a dictionary was because I could follow the arguements in the TweenService:Create() function.

TweenCreate

I think I understand it, but I don’t know… it’s kinda weird.

If it’s asking for a dictionary, wouldn’t that mean you should put all of the values into it and then fire it?

That’s usually the purpose of a dictionary as its a just a table I believe, so couldn’t you just do

goal = CameraPoints:GetChildren()

I skimmed over all the replies so idk if this was addressed but are all your parts anchored with cancollide set to true?

CanCollide should not be set to true if the parts are being used as markers.

1 Like