I’m hoping someone can help me create a smooth fade transition from one place to another when teleporting. I’ve outline the steps for this effect here:
Essentially if a player is transitioning from one place to another, the following will happen from their perspective:
Player screen shows Place A
Player screen fades out to black
Player screen will remain black while player teleports from Place A to Place B
Player screen fades in to world
Player screen shows Place B
This doc was somewhat helpful: Teleporting Between Places | Roblox Creator Documentation but there are a lot of moving parts to this in the server, client and ReplicatedFirst to have the fade effect be smooth. I’m also confused where / when I should create the FadeGui or destroy it, or maybe pass it from place to place using TeleportService:SetTeleportGui(teleportGui)(?)
local Game = game
local TweenService = Game:GetService("TweenService")
local ReplicatedFirst = Game:GetService("ReplicatedFirst")
ReplicatedFirst:RemoveDefaultLoadingScreen()
local Players = Game:GetService("Players")
local LocalPlayer = Players.LocalPlayer
local LoadingScreenGui = Instance.new("ScreenGui")
LoadingScreenGui.Name = "LoadingScreenGui"
LoadingScreenGui.IgnoreGuiInset = true
LoadingScreenGui.ResetOnSpawn = false
local LoadingScreenFrame = Instance.new("Frame")
LoadingScreenFrame.Name = "LoadingScreenFrame"
LoadingScreenFrame.BackgroundColor3 = Color3.new(0, 0, 0)
LoadingScreenFrame.Size = UDim2.new(1, 0, 1, 0)
LoadingScreenFrame.Parent = LoadingScreenGui
local PlayerGui = LocalPlayer:WaitForChild("PlayerGui")
LoadingScreenGui.Parent = PlayerGui
local Tween = TweenService:Create(LoadingScreenFrame, TweenInfo.new(5), {BackgroundTransparency = 1}) --Change '5'.
Tween:Play()
local function OnTeleport(TeleportState)
if TeleportState.Name == "InProgress" then
if Tween then Tween:Cancel() end
Tween = TweenService:Create(LoadingScreenFrame, TweenInfo.new(3), {BackgroundTransparency = 0}) --Change '3'.
end
end
LocalPlayer.OnTeleport:Connect(OnTeleport)
The fade out to black doesn’t seem to be happening quick enough, the player gets teleported before their screen fades to black
if TeleportState.Name == "InProgress" then
Changing ‘InProgress’ to ‘Started’ may resolve this, alternatively you could play the tween, wait for its completion via TweenBase:Completed:Wait() and then issue the teleport request.
The player still sees the default loading screen when entering the new place
Could be a bug relating to RemoveDefaultLoadingScreen.
I don’t think there is a bug… I think you need to set the gui to load immediately with TeleportService:SetTeleportGui(teleportGui). The fade is less important then having a consistent screen for the entire duration of the teleport to make the transition seamless.
Doors does this well with a black “Loading…” screen for example:
There’s a small hiccup when changing servers but it’s pretty much the best you can do at the moment I think. I’ll continue to play around with this… appreciate the help though.
This sets the gui when teleporting from a place not the gui when teleporting to a place. If RemoveDefaultLoadingScreen isn’t working for you then its either a bug (related to the API method) or an issue with your game’s setup.
All I have in the test game is the code you posted within ReplicatedFirst and a simple server script to teleport the player. Are you seeing the same thing I’m seeing when testing?
The purpose of showing the Doors example is to show that there is not a bug with RemoveDefaultLoadingScreen as they seem to be correctly using it.
local Game = game
local ReplicatedFirst = Game:GetService("ReplicatedFirst")
ReplicatedFirst:RemoveDefaultLoadingScreen()
local TeleportService = Game:GetService("TeleportService")
local TweenService = Game:GetService("TweenService")
local Players = Game:GetService("Players")
local LocalPlayer = Players.LocalPlayer
local PlayerGui = LocalPlayer:WaitForChild("PlayerGui")
local function OnPlayerTeleport(TeleportStatus)
if TeleportStatus.Name ~= "Started" then return end
local FadeIn = TweenService:Create(PlayerGui.LoadingScreenGui.LoadingScreenFrame, TweenInfo.new(5), {BackgroundTransparency = 0}) --Fade in tween.
end
local function OnLocalPlayerArrivedFromTeleport(LoadingScreenGui)
TeleportService:SetTeleportGui(LoadingScreenGui)
local FadeOut = TweenService:Create(LoadingScreenGui.LoadingScreenFrame, TweenInfo.new(5), {BackgroundTransparency = 1}) --Fade out tween.
FadeOut:Play()
end
LocalPlayer.OnTeleport:Connect(OnPlayerTeleport)
TeleportService.LocalPlayerArrivedFromTeleport:Connect(OnLocalPlayerArrivedFromTeleport)
local LoadingScreenGui = TeleportService:GetArrivingTeleportGui()
if not LoadingScreenGui then
LoadingScreenGui = Instance.new("ScreenGui")
LoadingScreenGui.Name = "LoadingScreenGui"
LoadingScreenGui.IgnoreGuiInset = true
LoadingScreenGui.ResetOnSpawn = false
LoadingScreenGui.Parent = PlayerGui
local LoadingScreenFrame = Instance.new("Frame")
LoadingScreenFrame.Name = "LoadingScreenFrame"
LoadingScreenFrame.BackgroundColor3 = Color3.new(0, 0, 0)
LoadingScreenFrame.Size = UDim2.new(1, 0, 1, 0)
LoadingScreenFrame.Parent = LoadingScreenGui
task.spawn(OnLocalPlayerArrivedFromTeleport, LoadingScreenGui)
end
I realized the real problem I’m trying to solve is keeping a black screen on throughout teleporting, then I can always fade the black screen out and in before and after teleporting respectively.
I found something that works:
In ReplicatedFirst LocalScript
local ReplicatedFirst = game:GetService("ReplicatedFirst")
-- Remove default loading screen
ReplicatedFirst:RemoveDefaultLoadingScreen()
local TeleportService = game:GetService("TeleportService")
-- Get arriving teleport gui
local loadingGui = TeleportService:GetArrivingTeleportGui()
local guiToAddToPlayer
if not loadingGui then
-- player entered experience
guiToAddToPlayer = ReplicatedFirst.EnterGui
else
-- player entered place from other place within experience
guiToAddToPlayer = loadingGui
end
local Players = game:GetService("Players")
local playerGui = Players.LocalPlayer:WaitForChild("PlayerGui")
-- Set local player's gui to guiToAddToPlayer
guiToAddToPlayer.Parent = playerGui
-- Wait some time (can do gui animations here)
task.wait(5)
-- Destroy the gui
guiToAddToPlayer:Destroy()
I created two guis - one for entering the experience (EnterGui), and one for teleporting from another place within the experience (LoadingGui). guiToAddToPlayer is only needed for the start place, any other place would always use loadingGui.
Only other thing you need is to set the teleport gui on the Client:
In StarterPlayerScripts LocalScript
local TeleportService = game:GetService("TeleportService")
local ReplicatedFirst = game:GetService("ReplicatedFirst")
TeleportService:SetTeleportGui(ReplicatedFirst:WaitForChild("LoadingGui"))
Here’s what the result looks like:
The API is all over the place for TeleportService… appreciate the help.
The event fired immediately for me when testing and I considered it the better approach as it provides both the loading screen gui and teleport data in a single operation rather than two individual operations (more performant). The snippet I provided does use GetArrivingTeleportGui too.
Additionally the documentation proceeds to provide a code snippet similar to mine indicating that the event/signal should be used for loading screens/teleport data.
local TeleportService = game:GetService("TeleportService")
local Players = game:GetService("Players")
local ReplicatedFirst = game:GetService("ReplicatedFirst")
TeleportService.LocalPlayerArrivedFromTeleport:Connect(function(customLoadingScreen, teleportData)
local playerGui = Players.LocalPlayer:WaitForChild("PlayerGui")
ReplicatedFirst:RemoveDefaultLoadingScreen()
customLoadingScreen.Parent = playerGui
-- animate screen here
wait(5)
-- destroy screen
customLoadingScreen:Destroy()
end)