如果您想构建一个拥有许多独特地点的体验,例如一个幻想世界与多个镇、城堡、地牢和广阔森林的宇宙,您可以使用 TeleportService 来启用用户在宇宙、服务器或甚至另一个体验之间进行传送。
设置传送
要启用体验中的传送,请使用 TeleportService:TeleportAsync() 。方法接受三个参数:
- 用户可以传送到的 PlaceId
- 包含用于传送用户的 Player 实例的阵列。
- 可选的 TeleportOptions 实例,包含 TeleportAsync() 调用的自定义属性。
local Players = game:GetService("Players")local TeleportService = game:GetService("TeleportService")local TARGET_PLACE_ID = 1234 -- 替换为自己的地点IDlocal playerToTeleport = Players:GetPlayers()[1] -- 获取体验中的第一个用户TeleportService:TeleportAsync(TARGET_PLACE_ID, {playerToTeleport}, teleportOptions)
如果您想在设置传送时采取错误处理措施,请参阅如何处理失败的传送。
启用跨体验传送
为了安全目的,将用户从你的体验传送到其他拥有者的体验,或者相反,默认失败。要启用跨体验传送,请打开 游戏设置 > 安全 > 并在 Studio 启用 允许第三方传送 。
创建自定义传送屏幕
当用户触发传送时,他们会看到标准的 Roblox 加载屏幕,等待新地点加载。您可以通过调用 TeleportService:SetTeleportGui() 在客户端上增加一个自定义传送屏幕来提高用户沉浸度,然后通过 ScreenGui 在用户传送之前使用来传送用户。以下示例设置了自定义 ScreenGui 位于 ReplicatedStorage 中的加载屏幕,当发生传送时。它不在 ScreenGui 内运行任何脚本。
local TeleportService = game:GetService("TeleportService")local ReplicatedStorage = game:GetService("ReplicatedStorage")local teleportGui = ReplicatedStorage.TeleportGuiTeleportService:SetTeleportGui(teleportGui)
自定义传送选项
您可以通过设置 传送用户到特定服务器 和 传送用户数据与传送一起 来自定义传送,例如 实例设置和传给 方法 。
传送到特定服务器
要将用户传送到特定服务器,请使用 TeleportOptions 设置目标服务器,然后传给 TeleportService:TeleportAsync() 方法。如果您未指定服务器,用户将被传送到匹配的公共服务器。列表中第一个用户的信息用于匹配到那个公共服务器。
要将用户传送到特定的公共服务器,将 TeleportOptions.ServerInstanceId 属性设置为有效的实例 ID,这是公共服务器的唯一标识符。
local teleportOptions = Instance.new("TeleportOptions")teleportOptions.ServerInstanceId = targetServerId
要将用户传送到特定保留服务器,设置一个有效的 TeleportOptions.ReservedServerAccessCode , 这是进入保留服务器的唯一代码。
local teleportOptions = Instance.new("TeleportOptions")teleportOptions.ReservedServerAccessCode = reservedServerCode
要将用户传送到新保留服务器,将 TeleportOptions.ShouldReserveServer 设置为真。
local teleportOptions = Instance.new("TeleportOptions")teleportOptions.ShouldReserveServer = true
将用户数据与传送一起发送
将用户在不同地点之间传送,将与该用户相关的本地数据丢弃。您可以使用以下方法来处理地点之间的数据持久性。
要将基本 非安全 数据从一个地方发送到另一个地场景,在将其传给 TeleportAsync() 之前调用 TeleportOptions:SetTeleportData() 。
local teleportData = {randomNumber = RNG:NextInteger(1, 100),}local teleportOptions = Instance.new("TeleportOptions")teleportOptions:SetTeleportData(teleportData)
要从服务器上的传送获取用户的所有数据,请使用 Player:GetJoinData() 函数,该函数返回包含用户相关数据的词典。
local Players = game:GetService("Players")
local function onPlayerAdded(player)
local joinData = player:GetJoinData()
local teleportData = joinData.TeleportData
local randomNumber = teleportData.randomNumber
print(player.Name .. "joined with the number" .. randomNumber)
end
Players.PlayerAdded:Connect(onPlayerAdded)
要仅从客户端中恢复传送数据,您可以使用 TeleportService:GetLocalPlayerTeleportData()。
处理失败的传送
像任何涉及网络请求的 API 调用一样,传送可能会失败并抛出错误。将它们包装在受保护的调用中(pcall())。一些失败可以从重试中受益,尤其是涉及保留服务器的失败,因此我们建议在失败上重试一定数量的次数。
即使调用成功并启动传送,在最后时刻仍然可能失败,而不会抛出错误并将用户留在服务器上。当这发生时,它会触发 TeleportService.TeleportInitFailed 事件。
下面的例子 ModuleScript 定义了一个 SafeTeleport 函数来在受保护的调用中传送用户以实现重试逻辑。它还有一个 handleFailedTeleport 函数来处理在调用成功但传送未发生的情况。
local TeleportService = game:GetService("TeleportService")
local ATTEMPT_LIMIT = 5
local RETRY_DELAY = 1
local FLOOD_DELAY = 15
local function SafeTeleport(placeId, players, options)
local attemptIndex = 0
local success, result -- 在循环外定义 pcall 结果,以便可以稍后报告结果
repeat
success, result = pcall(function()
return TeleportService:TeleportAsync(placeId, players, options) -- 将用户传送到受保护的调用中以防出错
end)
attemptIndex += 1
if not success then
task.wait(RETRY_DELAY)
end
until success or attemptIndex == ATTEMPT_LIMIT -- 如果调用成功或重试限制已达到,停止尝试传送
if not success then
warn(result) -- 将失败原因打印到输出
end
return success, result
end
local function handleFailedTeleport(player, teleportResult, errorMessage, targetPlaceId, teleportOptions)
if teleportResult == Enum.TeleportResult.Flooded then
task.wait(FLOOD_DELAY)
elseif teleportResult == Enum.TeleportResult.Failure then
task.wait(RETRY_DELAY)
else
-- 如果传送无效,报告错误而不是重试
error(("Invalid teleport [%s]: %s"):format(teleportResult.Name, errorMessage))
end
SafeTeleport(targetPlaceId, {player}, teleportOptions)
end
TeleportService.TeleportInitFailed:Connect(handleFailedTeleport)
return SafeTeleport
SafeTeleport 函数收到与 TeleportAsync() 函数相同的参数。您可以使用以下 ModuleScript 函数与 SafeTeleport 函数来从体验中的任何地点进行传送,以减少失败的传送。
local Players = game:GetService("Players")local ServerScriptService = game:GetService("ServerScriptService")local SafeTeleport = require(ServerScriptService.SafeTeleport)local TARGET_PLACE_ID = 1818 -- 替换为自己的地点IDlocal playerToTeleport = Players:GetPlayers()[1] -- 获取游戏中的第一个用户SafeTeleport(TARGET_PLACE_ID, {playerToTeleport}, teleportOptions)