許多遊戲被劃分為多個 地點,例如一個擁有城鎮、城堡、地牢和廣闊森林的奇幻世界。使用 TeleportService 將用戶在地點之間、不同伺服器之間,甚至在其他遊戲之間進行傳送。
傳送玩家
要傳送玩家,使用 TeleportService:TeleportAsync()。此方法接受三個參數:
- 用戶要傳送到的 PlaceId。
- 包含您想要傳送的 Player 實例的數組。
- 一個可選的 TeleportOptions 實例,包含 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.Touched 或 ProximityPrompt.Triggered 事件來獲取單個 Player。然後,您可以檢查該玩家是否是某個隊伍的一部分 (Player.Team) 或派對 (Player.PartyId)。最後,如果您想要傳送整個小組而不僅僅是個人,您可以使用 Team:GetPlayers() 或 SocialService:GetPlayersByPartyId()。
配置安全傳送
三個設置處理傳送安全性。
| 設置 | 描述 |
|---|---|
| (創作者儀表板) 觀眾 > 訪問設置 > 地點的訪問控制 | 控制玩家是否可以加入您遊戲中的任何地點,或必須先加入 起始地點。 |
| (創作者儀表板) 地點 > 訪問 > 直接訪問控制 | 覆蓋您遊戲級別的 地點的訪問控制 設置,適用於非起始地點。 |
| (Studio) 文件 > 體驗設置 > 安全性 > 允許第三方傳送 | 控制從您的遊戲到 您不擁有的遊戲 的傳送。您可以將此設置保持禁用,仍然可以在您擁有的已發布遊戲之間傳送玩家。 |
地點的訪問控制 控制玩家傳送 進入 您的遊戲,是防止基於傳送的漏洞的最關鍵設置。

如果您選擇 完全開放,玩家可以通過來自任何遊戲的傳送加入您遊戲中的任何地點,包括深層鏈接、遊戲邀請、加入朋友等。
如果您的遊戲有多個地點,並且您希望朋友能夠輕鬆加入彼此,不論他們在哪個地點,這是一個不錯的選擇。如果您不選擇此選項,試圖在非起始地點加入朋友的玩家將會加入您遊戲的起始地點。
如果您選擇 限於同一宇宙,玩家只能通過您遊戲內的傳送加入非起始地點。此設置允許客戶端和伺服器發起的傳送。
如果您有一個不想 遷移到安全傳送 的舊遊戲,這是一個不錯的選擇。
如果您選擇 僅限於宇宙內的安全,玩家只能通過伺服器發起的傳送加入非起始地點。
如果您的遊戲在玩家可以訪問某些區域之前有嚴格的進度系統,這是一個不錯的選擇。如果您的遊戲有一個玩家不應該訪問的測試地點,或者對於僅使用保留伺服器的地點,這也是一個不錯的選擇。
遷移到安全傳送
如果您有一個現有的遊戲使用客戶端傳送,並希望要求伺服器發起的傳送,目標是將所有傳送邏輯從客戶端腳本移出並放入伺服器腳本中:
- 找到所有調用 Teleport() 的客戶端腳本。
- 在伺服器腳本中使用 TeleportAsync() 重新實現傳送。
創建自定義傳送畫面
當用戶觸發傳送時,他們會看到標準的 Roblox 加載畫面,等待新地點加載。如果需要,您可以通過在客戶端上調用 TeleportService:SetTeleportGui() 來添加自定義傳送畫面。
以下示例從 ReplicatedStorage 設置自定義的 ScreenGui。ScreenGui 中的任何腳本都 不會 執行。
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 SafeTeleportSafeTeleport 函數接收與 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)