I’m trying to make cutscenes. The camera’s cframe is not starting at my first parts index in my scene folder. It is starting in a random order, sometimes it will just start at index 3 and then 2 then 1. I just want it to go in my scene folder and go from part 1, part 2, part 3. I have tried doing a for_, loop with my collection service cause I did tag the parts for my cutscene but that did not work either I will show you an example of my for loop:
for i, CameraPart in ipairs(CameraParts) do
print(i, CameraPart.Name)
if CameraPart == CameraPart then
CameraIndex = i
break
end
end
The print statement printed out: 1 Stage 2
Nothing is working
local SceneFolder = workspace.SceneFolders
local currentPartIndex = 0
local function animateText()
currentTextIndex = (prevTextIndex % #TEXTS) + 1
prevTextIndex = currentTextIndex
local newText = TEXTS[currentTextIndex]
local textLabelSize = TextLabel.TextBounds
local textTweenIn = TweenService:Create(TextLabel, TweenInfo.new(1), {
TextTransparency = 0,
Size = UDim2.new(0, 586, 0, 98)
})
local textTweenOut = TweenService:Create(TextLabel, TweenInfo.new(1), {
TextTransparency = 1,
Size = UDim2.new(0, 586, 0, 98)
})
-- Get the current part in the scene folder based on the currentTextIndex
currentPartIndex = currentPartIndex % #SceneFolder:GetChildren() + 1
local currentPart = SceneFolder:GetChildren()[currentPartIndex]
textTweenOut.Completed:Connect(function()
currentText = newText
TextLabel.Text = currentText
textTweenIn:Play()
-- Set the camera's CFrame to the current part's CFrame
Camera.CFrame = CFrame.new(currentPart.Position)
end)
textTweenIn:Play()
local currentCharacterIndex = 0
while currentCharacterIndex < #newText do
currentCharacterIndex = currentCharacterIndex + 1
TextLabel.Text = newText:sub(1, currentCharacterIndex)
sound:Play()
wait(0.05)
sound:Stop()
end
wait(TEXT_DISPLAY_TIME)
textTweenOut:Play()
end
local t0 = os.clock()
while os.clock() - t0 < CUTSCENE_LENGTH do
animateText()
RunService.Stepped:Wait()
end
-- enable control of character and camera after cutscene
Humanoid:ChangeState(Enum.HumanoidStateType.GettingUp)
Camera.CameraType = Enum.CameraType.Custom
Have you tried indexing the parts by their names, not their indexes in the array? In the following example, cameraParts is a Folder, and its children are named like “1”, “2”, “3”, etc:
for i = 1, #cameraParts:GetChildren() do
--[[
Get the current camera part by using
`cameraParts[i]`.
`cameraParts[i]` is not different than `cameraParts["2"]` (if `i` is `2`),
and is like `cameraParts:FindFirstChild("2")`.
]]
end
I don’t think that a table of children will follow the order in which the children were added. I could be wrong, though. However, this seems to be your problem.
Ok so I did this:
It is still not indexing at Scene1 instead its going to Scene3 and then Scene2 sometimes Scene2 and then Scene3. Im not getting any errors in the output. Whenever I print partName it prints all 3 names and when i print currentPart it prints out all 3 names
```for i = 1, #SceneFolder:GetChildren() do
local partName = "Scene" .. i
local currentPart = SceneFolder:FindFirstChild(partName)
if currentPart then
print(currentPart)
Camera.CFrame = CFrame.new(currentPart.Position)
end
end
end)```
I dont know maybe here is (almost) the full script I just left my TEXTS table out of it. and I switched up the method we are using with the table.sort but it still doesnt work:
local LocalPlayer = Players.LocalPlayer
local Character = LocalPlayer.Character or LocalPlayer.CharacterAdded:Wait()
local Humanoid = Character:WaitForChild("Humanoid")
local Camera = workspace.Camera
local RunService = game:GetService("RunService")
local TweenService = game:GetService("TweenService")
local Gui = script.DialogueBox
local TextLabel = Gui.TextLabel
--- CAMERAS--------------------------------------------------------------
local CollectionService = game:GetService("CollectionService")
local CutsceneCameras = CollectionService:GetTagged("CutsceneCameras")
Camera.CameraType = Enum.CameraType.Scriptable
local CUTSCENE_LENGTH = 30 -- length of cutscene in seconds
local TEXT_DISPLAY_TIME = 2 -- time to display each line of text in seconds
------------------------------------------------------------------------------
local ConnectRemote = game.ReplicatedStorage.Remotes.Connect
Humanoid:ChangeState(Enum.HumanoidStateType.Physics)
-- display cutscene GUI and start animating text
TextLabel.Visible = true
script.Parent.Visible = false
local currentTextIndex = 1
local currentText = TEXTS[currentTextIndex]
TextLabel.Text = currentText
local sound = Gui.Sound
local prevTextIndex = 0
local SceneFolder = workspace.SceneFolders -- Replace "SceneFolder" with the name of your scene folder
local currentPartIndex = 0
-- Get the current part in the scene folder based on the currentPartIndex
currentPartIndex = currentPartIndex % #SceneFolder:GetChildren() + 1
local currentPart = SceneFolder:GetChildren()[currentPartIndex]
local sceneChildren = SceneFolder:GetChildren()
table.sort(sceneChildren, function(a, b)
return a.Name < b.Name
end)
local function animateText()
currentTextIndex = (prevTextIndex % #TEXTS) + 1
prevTextIndex = currentTextIndex
local newText = TEXTS[currentTextIndex]
local textLabelSize = TextLabel.TextBounds
local textTweenIn = TweenService:Create(TextLabel, TweenInfo.new(1), {
TextTransparency = 0,
Size = UDim2.new(0, 586, 0, 98)
})
local textTweenOut = TweenService:Create(TextLabel, TweenInfo.new(1), {
TextTransparency = 1,
Size = UDim2.new(0, 586, 0, 98)
})
textTweenOut.Completed:Connect(function()
currentText = newText
TextLabel.Text = currentText
textTweenIn:Play()
for i = 1, #sceneChildren do
local partName = "Scene" .. i
local currentPart = sceneChildren[i]
Camera.CFrame = currentPart.CFrame
end
end)
textTweenIn:Play()
local currentCharacterIndex = 0
while currentCharacterIndex < #newText do
currentCharacterIndex = currentCharacterIndex + 1
TextLabel.Text = newText:sub(1, currentCharacterIndex)
sound:Play()
wait(0.05)
sound:Stop()
end
wait(TEXT_DISPLAY_TIME)
textTweenOut:Play()
end
local t0 = os.clock()
while os.clock() - t0 < CUTSCENE_LENGTH do
animateText()
RunService.Stepped:Wait()
end
-- enable control of character and camera after cutscene
Humanoid:ChangeState(Enum.HumanoidStateType.GettingUp)
Camera.CameraType = Enum.CameraType.Custom
-- hide cutscene GUI
TextLabel.Visible = false
script.Parent.Visible = true
script.Parent.MouseButton1Click:Connect(function()
script.Parent.Parent.Visible = false
Character.HumanoidRootPart.Anchored = false
Character.Humanoid.WalkSpeed = 16
Character.Humanoid.JumpPower = 59
ConnectRemote:FireServer("Move")
end)
If you’re using that currentPartIndex in the loop, I believe so.
I do think that the code before the loop is “interfering” with it.
It seems strange that it’s going out of order even though the loop’s index starts at 1, that’s why I don’t think it’s the loop itself.
And you’re saying that it’s “starting” at the 3rd index, which means you see it being set to the 1st and 2nd, too?
No I see it starting at the 3rd index. Whenever the player joins the game the cutscene goes to the 3rd part. I have it so as soon as the player joins the game, text displays, and when the text gets done displaying it moves to the next line of text in my array, when that next line of text starts my camera goes to part 3 and not 1 I only see it being set to 3 and then 2 but I never get to see 1
OK. I am trying to go along with your original code – I don’t know how your current code looks now. Also, the loop I provided was just an example of indexing parts by their names, so you do not actually need it.
As I stated above, you don’t actually need the loop, so forget it. However, the idea of indexing the parts by their names may be what you need.
In this example, pretend that camIndex is currentPartIndex, and camPart is currentPart:
local camIndex = 1 -- Start at 1, which isn't necessary depending on the math you use.
local function animate()
-- (I am just focusing on the camera parts in this function.)
-- Index the part. If there's a chance that the index would be higher than
-- the number of camera parts, you may want to do some checks:
--[[
if camIndex > #cameraParts:GetChildren() then
camIndex = 1
end
]]
local camPart = cameraParts[camIndex]
camera.CFrame = camPart.CFrame -- Set the camera's CFrame at sometime.
camIndex += 1 -- Increment the index for the next time the function gets called.
end