在地點之間傳送

*此內容是使用 AI(Beta 測試版)翻譯,可能含有錯誤。若要以英文檢視此頁面,請按一下這裡

許多遊戲被劃分為多個 地點,例如一個擁有城鎮、城堡、地牢和廣闊森林的奇幻世界。使用 TeleportService 將用戶在地點之間、不同伺服器之間,甚至在其他遊戲之間進行傳送。

傳送玩家

要傳送玩家,使用 TeleportService:TeleportAsync()。此方法接受三個參數:

local Players = game:GetService("Players")
local TeleportService = game:GetService("TeleportService")
local TARGET_PLACE_ID = 12345678901234 -- 替換為您自己的
local playerToTeleport = Players:GetPlayers()[1] -- 獲取遊戲中的第一個用戶
TeleportService:TeleportAsync(TARGET_PLACE_ID, {playerToTeleport})

要獲取適當的玩家進行傳送,您可以使用 BasePart.TouchedProximityPrompt.Triggered 事件來獲取單個 Player。然後,您可以檢查該玩家是否是某個隊伍的一部分 (Player.Team) 或派對 (Player.PartyId)。最後,如果您想要傳送整個小組而不僅僅是個人,您可以使用 Team:GetPlayers()SocialService:GetPlayersByPartyId()

配置安全傳送

三個設置處理傳送安全性。

設置描述
(創作者儀表板) 觀眾 > 訪問設置 > 地點的訪問控制控制玩家是否可以加入您遊戲中的任何地點,或必須先加入 起始地點
(創作者儀表板) 地點 > 訪問 > 直接訪問控制覆蓋您遊戲級別的 地點的訪問控制 設置,適用於非起始地點。
(Studio) 文件 > 體驗設置 > 安全性 > 允許第三方傳送控制從您的遊戲到 您不擁有的遊戲 的傳送。您可以將此設置保持禁用,仍然可以在您擁有的已發布遊戲之間傳送玩家。

地點的訪問控制 控制玩家傳送 進入 您的遊戲,是防止基於傳送的漏洞的最關鍵設置。

創作者中心的地點訪問控制

  • 如果您選擇 完全開放,玩家可以通過來自任何遊戲的傳送加入您遊戲中的任何地點,包括深層鏈接、遊戲邀請、加入朋友等。

    如果您的遊戲有多個地點,並且您希望朋友能夠輕鬆加入彼此,不論他們在哪個地點,這是一個不錯的選擇。如果您不選擇此選項,試圖在非起始地點加入朋友的玩家將會加入您遊戲的起始地點。

  • 如果您選擇 限於同一宇宙,玩家只能通過您遊戲內的傳送加入非起始地點。此設置允許客戶端和伺服器發起的傳送。

    如果您有一個不想 遷移到安全傳送 的舊遊戲,這是一個不錯的選擇。

  • 如果您選擇 僅限於宇宙內的安全,玩家只能通過伺服器發起的傳送加入非起始地點。

    如果您的遊戲在玩家可以訪問某些區域之前有嚴格的進度系統,這是一個不錯的選擇。如果您的遊戲有一個玩家不應該訪問的測試地點,或者對於僅使用保留伺服器的地點,這也是一個不錯的選擇。

遷移到安全傳送

如果您有一個現有的遊戲使用客戶端傳送,並希望要求伺服器發起的傳送,目標是將所有傳送邏輯從客戶端腳本移出並放入伺服器腳本中:

  1. 找到所有調用 Teleport() 的客戶端腳本。
  2. 將這些調用更改為觸發 遠程事件。或者,您可以將調用更改為使用 ProximityPromptsClickDetectors,甚至僅使用 BasePart.Touched 事件。
  3. 在伺服器腳本中使用 TeleportAsync() 重新實現傳送。
  4. 當不再存在 Teleport() 調用時,將 地點的訪問控制 更改為 安全

創建自定義傳送畫面

當用戶觸發傳送時,他們會看到標準的 Roblox 加載畫面,等待新地點加載。如果需要,您可以通過在客戶端上調用 TeleportService:SetTeleportGui() 來添加自定義傳送畫面。

以下示例從 ReplicatedStorage 設置自定義的 ScreenGuiScreenGui 中的任何腳本都 不會 執行。

local TeleportService = game:GetService("TeleportService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local teleportGui = ReplicatedStorage.TeleportGui
TeleportService:SetTeleportGui(teleportGui)

自定義傳送選項

您可以通過設置 TeleportOptions 實例並將其傳遞給 TeleportService:TeleportAsync() 方法來自定義傳送,例如 將用戶傳送到特定伺服器隨傳送發送用戶數據

傳送到特定伺服器

要將用戶傳送到特定伺服器,請使用 TeleportOptions 設置目標伺服器並將其傳遞給 TeleportAsync() 方法。如果您不指定伺服器,用戶將被傳送到公共伺服器;列表中第一個用戶的信息將用於匹配。

要將用戶傳送到特定的公共伺服器,請將 TeleportOptions.ServerInstanceId 屬性設置為有效的實例 ID,這是公共伺服器的唯一標識符。

local teleportOptions = Instance.new("TeleportOptions")
teleportOptions.ServerInstanceId = targetServerId

要將用戶傳送到特定的保留伺服器,請設置有效的 TeleportOptions.ReservedServerAccessCode,這是進入保留伺服器的唯一代碼。

local teleportOptions = Instance.new("TeleportOptions")
teleportOptions.ReservedServerAccessCode = reservedServerCode

要將用戶傳送到新的保留伺服器,請將 TeleportOptions.ShouldReserveServer 設置為 true。

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() 函數,該函數返回一個包含 TeleportData 鍵的字典。

local Players = game:GetService("Players")
local function onPlayerAdded(player)
local joinData = player:GetJoinData()
local teleportData = joinData.TeleportData
local randomNumber = teleportData.randomNumber
print(player.Name .. " 以數字 " .. 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(("無效的傳送 [%s]: %s"):format(teleportResult.Name, errorMessage))
end
SafeTeleport(targetPlaceId, {player}, teleportOptions)
end
TeleportService.TeleportInitFailed:Connect(handleFailedTeleport)
return SafeTeleport

SafeTeleport 函數接收與 TeleportAsync() 函數相同的參數。您可以使用以下腳本與 SafeTeleport 函數從遊戲中的任何地方執行傳送:

local Players = game:GetService("Players")
local TeleportService = game:GetService("TeleportService")
local ServerScriptService = game:GetService("ServerScriptService")
local SafeTeleport = require(ServerScriptService.SafeTeleport)
local PLACE_TO_TELEPORT_TO = 12345678
local function teleport(touchPart)
local playerToTeleport = game.Players:GetPlayerFromCharacter(touchPart.Parent)
if playerToTeleport then
SafeTeleport(PLACE_TO_TELEPORT_TO, {playerToTeleport})
end
end
script.Parent.Touched:Connect(teleport)
©2026 Roblox Corporation、Roblox、Roblox 標誌及 Powering Imagination 是我們在美國及其他國家地區的部分註冊與未註冊商標。