Nhiều trò chơi được phân chia thành nhiều địa điểm, chẳng hạn như một thế giới huyền bí với các thị trấn, lâu đài, hầm ngục và một khu rừng rộng lớn. Sử dụng TeleportService để dịch chuyển người dùng giữa các địa điểm, đến các máy chủ khác hoặc thậm chí đến các trò chơi khác.
Dịch chuyển người chơi
Để dịch chuyển người chơi, sử dụng TeleportService:TeleportAsync(). Phương thức này chấp nhận ba tham số:
- PlaceId mà người dùng sẽ dịch chuyển tới.
- Một mảng chứa các phiên bản Player mà bạn muốn dịch chuyển.
- Một thể hiện tùy chọn TeleportOptions tùy chọn chứa các thuộc tính tùy chỉnh cho cuộc gọi TeleportAsync().
local Players = game:GetService("Players")local TeleportService = game:GetService("TeleportService")local TARGET_PLACE_ID = 12345678901234 -- thay thế bằng ID của bạnlocal playerToTeleport = Players:GetPlayers()[1] -- lấy người dùng đầu tiên trong trò chơiTeleportService:TeleportAsync(TARGET_PLACE_ID, {playerToTeleport})
Để có được người chơi phù hợp để dịch chuyển, bạn có thể sử dụng sự kiện BasePart.Touched hoặc ProximityPrompt.Triggered để lấy một Player cá nhân. Sau đó, bạn có thể kiểm tra xem người chơi có phải là một phần của đội (Player.Team) hoặc tiệc (Player.PartyId) không. Cuối cùng, bạn có thể sử dụng Team:GetPlayers() hoặc SocialService:GetPlayersByPartyId() nếu bạn muốn dịch chuyển toàn bộ nhóm thay vì chỉ cá nhân.
Cấu hình dịch chuyển an toàn
Ba cài đặt xử lý bảo mật dịch chuyển.
| Cài đặt | Mô tả |
|---|---|
| (Bảng điều khiển Người sáng tạo) Đối tượng > Cài đặt truy cập > Kiểm soát truy cập cho các địa điểm | Kiểm soát xem người chơi có thể tham gia bất kỳ địa điểm nào trong trò chơi của bạn hoặc phải tham gia trước vào địa điểm bắt đầu. |
| (Bảng điều khiển Người sáng tạo) Địa điểm > Truy cập > Kiểm soát truy cập trực tiếp | Ghi đè cài đặt Kiểm soát truy cập cho các địa điểm ở mức trò chơi cho một địa điểm không phải là địa điểm bắt đầu. |
| (Studio) Tệp > Cài đặt trải nghiệm > Bảo mật > Cho phép Dịch chuyển của bên thứ ba | Kiểm soát việc dịch chuyển từ trò chơi của bạn đến các trò chơi mà bạn không sở hữu. Bạn có thể giữ cài đặt này tắt và vẫn dịch chuyển người chơi giữa các trò chơi đã xuất bản mà bạn sở hữu. |
Kiểm soát truy cập cho các địa điểm kiểm soát việc người chơi dịch chuyển vào trò chơi của bạn và là cài đặt quan trọng nhất để ngăn chặn các hành vi xấu dựa trên dịch chuyển.

Nếu bạn chọn Mở hoàn toàn, người chơi có thể tham gia bất kỳ địa điểm nào trong trò chơi của bạn thông qua các dịch chuyển từ bất kỳ trò chơi nào, bao gồm các liên kết sâu, lời mời trò chơi, tham gia bạn bè, và nhiều hơn nữa.
Đây là một lựa chọn tốt nếu trò chơi của bạn có nhiều địa điểm và bạn muốn bạn bè có thể dễ dàng tham gia vào nhau bất kể họ đang ở địa điểm nào. Nếu bạn không chọn tùy chọn này, người chơi muốn tham gia bạn bè của họ trong các địa điểm không phải bắt đầu sẽ thay vào đó tham gia vào địa điểm bắt đầu của trò chơi của bạn.
Nếu bạn chọn Giới hạn trong cùng vũ trụ, người chơi chỉ có thể tham gia các địa điểm không phải bắt đầu thông qua các dịch chuyển trong trò chơi của bạn. Cài đặt này cho phép cả dịch chuyển do client và server khởi xướng.
Đây là một lựa chọn tốt nếu bạn có một trò chơi cũ mà bạn không muốn di chuyển sang dịch chuyển an toàn.
Nếu bạn chọn Bảo mật chỉ trong vũ trụ, người chơi chỉ có thể tham gia các địa điểm không phải bắt đầu thông qua các dịch chuyển do server khởi xướng trong trò chơi này.
Đây là một lựa chọn tốt nếu trò chơi của bạn có một hệ thống tiến trình nghiêm ngặt trước khi người chơi có thể truy cập vào một số khu vực nhất định. Nó cũng là một lựa chọn tốt nếu trò chơi của bạn có một địa điểm thử nghiệm mà người chơi không nên có quyền truy cập hoặc cho các địa điểm hoàn toàn sử dụng các máy chủ được dự trữ.
Di chuyển sang dịch chuyển an toàn
Nếu bạn có một trò chơi hiện có sử dụng dịch chuyển từ phía client và muốn yêu cầu các dịch chuyển do server khởi xướng, mục tiêu là chuyển tất cả logic dịch chuyển ra khỏi các kịch bản client và vào các kịch bản server:
- Tìm tất cả các kịch bản client gọi Teleport().
- Thay đổi các cuộc gọi này thành thay vào đó kích hoạt các sự kiện từ xa. Hoặc, bạn có thể thay đổi các cuộc gọi này thành sử dụng ProximityPrompts, ClickDetectors, hoặc thậm chí chỉ là sự kiện BasePart.Touched.
- Triển khai lại dịch chuyển trong một kịch bản server sử dụng TeleportAsync().
- Khi không còn cuộc gọi nào Teleport() tồn tại, thay đổi Kiểm soát truy cập cho các địa điểm thành An toàn.
Tạo màn hình dịch chuyển tùy chỉnh
Khi một người dùng kích hoạt một dịch chuyển, họ sẽ thấy màn hình tải tiêu chuẩn của Roblox khi họ chờ địa điểm mới tải. Nếu muốn, bạn có thể thêm một màn hình dịch chuyển tùy chỉnh bằng cách gọi TeleportService:SetTeleportGui() trên client.
Ví dụ sau đặt một ScreenGui tùy chỉnh từ ReplicatedStorage. Các kịch bản trong ScreenGui không chạy.
local TeleportService = game:GetService("TeleportService")local ReplicatedStorage = game:GetService("ReplicatedStorage")local teleportGui = ReplicatedStorage.TeleportGuiTeleportService:SetTeleportGui(teleportGui)
Tùy chỉnh tùy chọn dịch chuyển
Bạn có thể tùy chỉnh các dịch chuyển, chẳng hạn như dịch chuyển người dùng đến một máy chủ cụ thể và gửi dữ liệu người dùng cùng với các dịch chuyển, bằng cách đặt thể hiện TeleportOptions và truyền nó vào phương thức TeleportService:TeleportAsync().
Dịch chuyển đến các máy chủ cụ thể
Để dịch chuyển người dùng đến các máy chủ cụ thể, đặt máy chủ mục tiêu bằng TeleportOptions và truyền nó vào phương thức TeleportAsync(). Nếu bạn không chỉ định máy chủ, người dùng sẽ được dịch chuyển vào một máy chủ công cộng; thông tin của người dùng đầu tiên trong danh sách sẽ được sử dụng để ghép đôi.
Để dịch chuyển người dùng đến một máy chủ công cộng cụ thể, đặt thuộc tính TeleportOptions.ServerInstanceId như một ID thể hiện hợp lệ, đó là một định danh duy nhất cho một máy chủ công cộng.
local teleportOptions = Instance.new("TeleportOptions")teleportOptions.ServerInstanceId = targetServerId
Để dịch chuyển người dùng đến một máy chủ dự trữ cụ thể, đặt một TeleportOptions.ReservedServerAccessCode hợp lệ, đây là mã duy nhất để vào một máy chủ dự trữ.
local teleportOptions = Instance.new("TeleportOptions")teleportOptions.ReservedServerAccessCode = reservedServerCode
Để dịch chuyển người dùng đến một máy chủ dự trữ mới, đặt TeleportOptions.ShouldReserveServer thành true.
local teleportOptions = Instance.new("TeleportOptions")teleportOptions.ShouldReserveServer = true
Gửi dữ liệu người dùng cùng với dịch chuyển
Dịch chuyển một người dùng giữa các địa điểm sẽ loại bỏ bất kỳ dữ liệu cục bộ nào liên quan đến người dùng đó. Bạn có thể sử dụng các phương pháp sau để xử lý sự tồn tại dữ liệu giữa các địa điểm:
Nếu trò chơi của bạn sử dụng dữ liệu người dùng an toàn như tiền trong trò chơi hoặc kho, hãy triển khai kho dữ liệu hoặc kho bộ nhớ để duy trì dữ liệu từ địa điểm này sang địa điểm khác.
Để gửi dữ liệu không an toàn cơ bản từ địa điểm này sang địa điểm khác, hãy gọi TeleportOptions:SetTeleportData() trước khi truyền nó vào TeleportAsync(). Đừng chuyển dữ liệu an toàn bằng cách sử dụng phương pháp này; dữ liệu này có thể nhìn thấy bởi client và không được mã hóa.
local teleportData = {randomNumber = RNG:NextInteger(1, 100),}local teleportOptions = Instance.new("TeleportOptions")teleportOptions:SetTeleportData(teleportData)
Để lấy tất cả dữ liệu khi một người dùng đến địa điểm mới sau một lần dịch chuyển, sử dụng hàm Player:GetJoinData(), hàm này trả về một từ điển với khóa 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 .. " đã tham gia với số " .. randomNumber)
end
Players.PlayerAdded:Connect(onPlayerAdded)
Để chỉ lấy dữ liệu dịch chuyển trên client, bạn có thể sử dụng TeleportService:GetLocalPlayerTeleportData().
Xử lý các dịch chuyển không thành công
Giống như bất kỳ cuộc gọi API nào liên quan đến yêu cầu mạng, các dịch chuyển có thể không thành công và ném ra lỗi. Bọc chúng trong các cuộc gọi bảo vệ (pcall()). Một số lỗi có thể được mang lại lợi ích từ các lần thử lại, đặc biệt là những lỗi liên quan đến các máy chủ dự trữ, vì vậy chúng tôi khuyên bạn nên thử lại một số lần trong trường hợp không thành công.
Ngay cả khi cuộc gọi thành công và dịch chuyển được khởi đầu, nó vẫn có thể thất bại vào lúc cuối mà không ném ra lỗi và để người dùng ở lại trong máy chủ. Khi điều này xảy ra, nó kích hoạt sự kiện TeleportService.TeleportInitFailed.
Ví dụ sau ModuleScript trả về một hàm SafeTeleport duy nhất dịch chuyển người chơi trong một cuộc gọi bảo vệ với logic thử lại. Nó cũng có một hàm handleFailedTeleport để xử lý các tình huống mà cuộc gọi đã thành công, nhưng dịch chuyển không xảy ra.
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 -- định nghĩa kết quả pcall ngoài vòng lặp để có kết quả có thể báo cáo sau này
repeat
success, result = pcall(function()
return TeleportService:TeleportAsync(placeId, players, options) -- dịch chuyển người dùng trong một cuộc gọi bảo vệ để tránh lỗi
end)
attemptIndex += 1
if not success then
task.wait(RETRY_DELAY)
end
until success or attemptIndex == ATTEMPT_LIMIT -- ngừng cố gắng dịch chuyển nếu cuộc gọi thành công, hoặc nếu giới hạn thử lại đã được đạt
if not success then
warn(result) -- in lý do thất bại ra output
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
-- nếu dịch chuyển không hợp lệ, báo cáo lỗi thay vì thử lại
error(("Dịch chuyển không hợp lệ [%s]: %s"):format(teleportResult.Name, errorMessage))
end
SafeTeleport(targetPlaceId, {player}, teleportOptions)
end
TeleportService.TeleportInitFailed:Connect(handleFailedTeleport)
return SafeTeleport
Hàm SafeTeleport nhận cùng các tham số như phương thức TeleportAsync(). Bạn có thể sử dụng kịch bản sau với hàm SafeTeleport để thực hiện các dịch chuyển từ bất kỳ đâu trong trò chơi của bạn:
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)