Kỹ thuật và chuyển đổi

*Nội dung này được dịch bằng AI (Beta) và có thể có lỗi. Để xem trang này bằng tiếng Anh, hãy nhấp vào đây.

Hướng dẫn này phác thảo một số kỹ thuật để sử dụng phát trực tuyến phiên bản trong trò chơi một cách hiệu quả và hiệu quả. Mặc dù không có giải pháp "một kích cỡ phù hợp với tất cả" cho việc thiết kế một trò chơi phát trực tuyến, nhưng việc làm theo các bước cấp cao này sẽ giúp bạn đi được phần lớn con đường.

Thuộc tính phát trực tuyến

Khi StreamingEnabled được bật cho đối tượng Workspace trong Studio, hãy đặt các thuộc tính liên quan của nó thành các giá trị được khuyến nghị sau:

Thuộc tínhKhuyến nghị
EnableSLIMAvatarsSử dụng Enabled để hiển thị các hình đại diện R15 như là những hình đại diện nhẹ, hoạt hình khi thích hợp. Xem hình đại diện SLIM để biết thêm thông tin.
ModelStreamingBehaviorSử dụng Improved để kích hoạt phát trực tuyến hiệu quả nhất cho Models có các phần tử con BasePart.
StreamingIntegrityModeSử dụng PauseOutsideLoadedArea để cân bằng tính toàn vẹn của gameplay mà không tạm dừng một cách không cần thiết hoặc quá thường xuyên.
StreamingMinRadiusSử dụng mặc định là 64 để tối đa hóa khả năng mà động cơ có thể thu nhỏ trò chơi cho các thiết bị cấu hình thấp.
StreamingTargetRadiusSử dụng mặc định là 1024 để đạt được sự cân bằng tốt giữa khả năng hiển thị cho người chơi trên các thiết bị cấu hình cao và một dấu chân bộ nhớ hợp lý.
StreamOutBehaviorSử dụng Opportunistic để cho phép khách hàng thu gom nội dung một cách quyết liệt, giảm đáng kể việc sử dụng bộ nhớ và giúp ngăn ngừa sự cố hết bộ nhớ.

Mức độ chi tiết của mô hình

Model.LevelOfDetail giúp lấp đầy nội dung Model không được phát trực tuyến bằng các lưới composite hoặc giả mạo nhẹ, làm cho thế giới trông hoàn chỉnh về mặt hình ảnh. SLIM (Mô hình tương tác nhẹ có thể mở rộng) đặc biệt hiệu quả, vì người chơi thường không thể phân biệt một lưới SLIM với bản gốc đã được phát trực tuyến hoàn toàn.

Để đạt được kết quả tốt nhất:

  • Nhóm các phần có liên quan về không gian và logic, ví dụ như tất cả các phần của một chiếc xe.
  • Đặt LevelOfDetail thành SLIM trên các mô hình chứa các lưới và phần tĩnh. Các mô hình được sửa đổi trong thời gian chạy hoặc phát hoạt ảnh không được hỗ trợ.
  • Giữ kích thước không gian của mỗi mô hình dưới ~64 studs khối để tăng khả năng toàn bộ mô hình thực sự được phát trực tuyến cùng nhau. Nếu một mô hình có kích thước rất lớn, hãy chia nó thành các mô hình mô-đun nhỏ hơn và áp dụng một LevelOfDetail phù hợp cho mỗi mô hình.

Cấu trúc mô hình

Ngoài việc thiết lập mức độ chi tiết của mô hình, cấu trúc và cài đặt của Models của bạn có ảnh hưởng đáng kể đến hiệu suất phát trực tuyến. Khi bạn xây dựng hoặc chuyển đổi một trò chơi hiện có:

  • Sử dụng mô hình nguyên tử cho nhóm logic — Khi một kịch bản cần truy cập tất cả các phần trong một mô hình, hãy đặt ModelStreamingMode của nó thành Atomic. Điều này cho phép các kịch bản phía khách hàng truy cập an toàn các thể hiện bên trong mô hình mà không sử dụng quá mức WaitForChild() (mặc dù các kịch bản như vậy vẫn phải sử dụng WaitForChild() cho mô hình nguyên tử tổng thể).

  • Giảm thiểu mô hình bền vững — Các mô hình bền vững tải sau khi tham gia và không bao giờ phát trực tuyến ra, chiếm dụng bộ nhớ vĩnh viễn. Đặt ModelStreamingMode của một mô hình thành Persistent chỉ khi nó phải luôn có sẵn và có thể truy cập cho các kịch bản mọi lúc.

  • Phân tách các mô hình chứa — Một mẫu không phát trực tuyến phổ biến là một Model khổng lồ chứa nhiều NPC, đồ vật hoặc nhóm tương tự. Dưới phát trực tuyến, các mô hình chứa giảm hiệu quả phát trực tuyến và chúng không tối ưu cho mức độ chi tiết của mô hình hoạt động tốt nhất với các thể hiện được nhóm lại gần nhau. Phân tách các mô hình chứa thành các mô hình nhỏ hơn với các phần gần nhau về mặt vật lý hoặc có liên quan về mặt logic.

  • Làm phẳng các cấu trúc mô hình lồng ghép sâu — Việc lồng ghép một mô hình bền vững bên trong một mô hình nguyên tử thực sự buộc mô hình nguyên tử phải hoạt động như một mô hình bền vững. Các cấu trúc phẳng dễ hiểu hơn dưới phát trực tuyến.

Hình đại diện SLIM

Các hình đại diện nền tảng bên ngoài khu vực đang được phát trực tuyến không hiển thị theo mặc định, nhưng việc bật Workspace.EnableSLIMAvatars sẽ hiển thị các hình đại diện R15 như là những hình đại diện nhẹ, hoạt hình khi thích hợp. Về cơ bản, động cơ:

  • Hiển thị một phiên bản SLIM khi một mô hình hình đại diện thực tế phát trực tuyến ra.
  • Hoán đổi giữa các đại diện SLIM và độ phân giải đầy đủ dựa trên tài nguyên có sẵn, ngay cả bên trong bán kính phát trực tuyến.
  • Giới hạn hoạt ảnh SLIM dựa trên tầm quan trọng của cảnh và băng thông có sẵn.

Hình đại diện SLIM hỗ trợ các nhân vật người chơi R15 với cơ thể, đầu động, khung R15 chuẩn hoặc nâng cao, và phụ kiện cứng/lớp. Hình đại diện R6, NPC và hình đại diện có tỷ lệ tùy chỉnh bị loại trừ. Để biết danh sách đầy đủ các cấu hình hình đại diện được hỗ trợ và bị loại trừ, dữ liệu hiệu suất và mẹo khắc phục sự cố, hãy xem hình đại diện SLIM.

Mẫu kịch bản

Các mẫu kịch bản sau đây thường bị ảnh hưởng bởi phát trực tuyến. Chiến lược đúng phụ thuộc vào ý định của mã, vì vậy mỗi mẫu liệt kê nhiều tùy chọn khi thích hợp.

Chỉ mục trực tiếp đến các thể hiện con

Việc chỉ mục vào các thể hiện con của Workspace bằng toán tử . sẽ ném ra lỗi nếu bất kỳ thể hiện nào trong đường dẫn không được phát trực tuyến. Điều tương tự cũng áp dụng cho FindFirstChild(), FindFirstChildWhichIsA(), và FindFirstChildOfClass() mà trả về nil nếu đứa trẻ chưa được phát trực tuyến.

Tra cứu thể hiện con
local house1 = workspace:FindFirstChild("House1") -- nil nếu "House1" chưa được phát trực tuyến
local door = workspace.House1.Door -- Hỏng nếu "House1" hoặc "Door" chưa được phát trực tuyến

Một mẫu tương tự là truy cập Humanoid hoặc các thể hiện con nhân vật khác trực tiếp bên trong một kết nối Player.CharacterAdded. Dưới phát trực tuyến, mô hình nhân vật được gán cho Workspace trước khi tất cả các thể hiện con của nó được sao chép, vì vậy việc chỉ mục trực tiếp sẽ thất bại.

Thể hiện con nhân vật
local Players = game:GetService("Players")
local player = Players.LocalPlayer
player.CharacterAdded:Connect(function(character)
local humanoid = character.Humanoid
end)

Nếu kịch bản không thể tiến triển mà không có một thể hiện, hãy chờ nó với WaitForChild():

Tra cứu thể hiện con
local house1 = workspace:WaitForChild("House1")
local door = house1:WaitForChild("Door")

Các thể hiện được gửi từ xa

Một tín hiệu RemoteEvent/RemoteFunction và thể hiện mà nó tham chiếu đến di chuyển độc lập, vì vậy tín hiệu có thể đến phía khách hàng trước khi thể hiện có mặt — hoặc thể hiện có thể không bao giờ có mặt. Hai nguyên nhân có thể xảy ra bao gồm:

  • Dưới phát trực tuyến, có thể có một chút độ trễ giữa khi một phần/mô hình được tạo trên máy chủ và khi nó được sao chép đến khách hàng. Về cơ bản, một phần được tham chiếu bởi một RemoteEvent/RemoteFunction có thể đơn giản là chưa tồn tại, ngay cả bên trong một khu vực đã được phát trực tuyến.

  • Gửi một tham chiếu phần/mô hình từ máy chủ đến khách hàng thông qua một RemoteEvent hoặc RemoteFunction yêu cầu rằng thể hiện được sao chép đến khách hàng nhận. Gửi một đường dẫn thể hiện dưới dạng chuỗi cũng gặp phải vấn đề tương tự, vì đường dẫn có thể giải quyết đến một vị trí không tồn tại trên khách hàng:

    Kịch bản phía khách hàng
    local ReplicatedStorage = game:GetService("ReplicatedStorage")
    local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
    remoteEvent.OnClientEvent:Connect(function(data)
    local checkpoint = data.checkpoint -- Lỗi nếu "checkpoint" chưa được phát trực tuyến
    local level = workspace.Levels[data.levelPath] -- Lỗi nếu đường dẫn chưa được phát trực tuyến
    end)

Nếu kịch bản phía khách hàng cần thể hiện để tiếp tục, hãy bao gồm WaitForChild() trước khi sử dụng nó. Lưu ý rằng điều này có thể chờ vô thời hạn nếu thể hiện không bao giờ được phát trực tuyến, vì vậy hãy xem xét việc thêm một thời gian chờ như tham số thứ hai của WaitForChild().

Khách hàng không đồng bộ

Sự không đồng bộ phía khách hàng nên được coi là một ngoại lệ, không phải là một mẫu thiết kế tiêu chuẩn. Việc giới thiệu các bản sao chỉ dành cho khách hàng hoặc thay đổi cha của các thể hiện cục bộ có thể tạo ra các vấn đề nghiêm trọng. Kiểm tra mã của bạn cho các vị trí phụ thuộc vào những loại thay đổi này tồn tại trên khách hàng.

Ví dụ, việc thay đổi cha của một thể hiện cục bộ từ ReplicatedStorage sang Workspace có thể làm cho thể hiện đó đủ điều kiện để được phát trực tuyến ra. Tương tự, việc sao chép một thể hiện cục bộ (Instance:Clone()) từ ReplicatedStorage vào Workspace tạo ra một bản sao chỉ dành cho khách hàng không còn là một phần của quy trình sao chép máy chủ và sẽ không nhận được các cập nhật thuộc tính từ thể hiện gốc thuộc máy chủ.

Khái niệm tương tự áp dụng khi gọi Instance:Destroy() trên khách hàng cho một đối tượng thuộc máy chủ. Điều này xóa thể hiện cục bộ nhưng máy chủ vẫn có nó, vì vậy nó sẽ phát trực tuyến trở lại với trạng thái gốc của nó khi đủ điều kiện.

Phát trực tuyến chủ động

Khi điểm đến tiếp theo của người chơi có thể được dự đoán, hãy thực hiện các cuộc gọi phía máy chủ đến Player:RequestStreamAroundAsync() để phát trực tuyến các khu vực tạm thời cho việc tải tạm thời, hoặc sử dụng Player:AddReplicationFocus() trên cơ sở hạn chế cho các khu vực nên được giữ lại cho đến khi được giải phóng một cách rõ ràng.

Ví dụ, khi một nhân vật người chơi sắp sửa dịch chuyển bằng cách thay đổi CFrame đến nhà của một người chơi khác ở một vị trí xa, bạn có thể tiền lấy khu vực đích để giảm thiểu hiện tượng pop-in và cung cấp một chuyển tiếp mượt mà hơn. Kịch bản sau đây cho thấy cách một sự kiện từ xa từ khách hàng đến máy chủ có thể được phát để di chuyển một nhân vật người chơi bằng phương pháp tiền lấy. Nếu yêu cầu tiền lấy thành công khi hàm trả về, bán kính tối thiểu xung quanh vị trí mục tiêu nên có mặt trên khách hàng.

Kịch bản máy chủ - Dịch chuyển nhân vật người chơi
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local teleportEvent = ReplicatedStorage:WaitForChild("TeleportEvent")
local function teleportPlayer(player, teleportTarget)
-- Yêu cầu phát trực tuyến xung quanh vị trí mục tiêu
player:RequestStreamAroundAsync(teleportTarget)
-- Dịch chuyển nhân vật
local character = player.Character
if character and character.Parent then
local currentPivot = character:GetPivot()
character:PivotTo(currentPivot * CFrame.new(teleportTarget))
end
end
-- Gọi hàm dịch chuyển khi khách hàng phát sự kiện từ xa
teleportEvent.OnServerEvent:Connect(teleportPlayer)

Đọc thuộc tính thể hiện

Khi một thể hiện phát trực tuyến ra, các cập nhật thuộc tính của nó không còn được sao chép đến khách hàng đó. Việc đọc các thuộc tính như BasePart.Position tiếp tục thành công nhưng trả về giá trị đã sao chép cuối cùng có thể đã lỗi thời một cách tùy ý.

local Players = game:GetService("Players")
local player = Players.LocalPlayer
-- Vị trí có thể đã lỗi thời nếu "target" đã phát trực tuyến ra
local dist = (target.Position - player.Character.HumanoidRootPart.Position).Magnitude

Di chuyển logic đến máy chủ, vì các kịch bản phía máy chủ thấy tất cả các thể hiện mọi lúc. Đây thường là tùy chọn đáng tin cậy nhất cho các kiểm tra khoảng cách và các logic nhạy cảm với vị trí khác.

Chờ trên đường dẫn quan trọng

Một số trò chơi không phát trực tuyến tải bản đồ của chúng bằng cách sao chép nó từ ReplicatedStorage vào Workspace, sau đó chờ nó trên khách hàng trước khi bỏ qua màn hình tải và báo hiệu sẵn sàng. Dưới phát trực tuyến, điều này sẽ treo vô thời hạn — nhân vật của khách hàng chưa được sinh ra, vì vậy không có tập trung sao chép, và thể hiện bản đồ không bao giờ phát trực tuyến vào.

Di chuyển logic màn hình tải để nó không phụ thuộc vào một thể hiện không gian cụ thể có mặt, ví dụ như báo hiệu sẵn sàng khi nhân vật đã sinh ra và khu vực xung quanh ngay lập tức đã được phát trực tuyến.

Xử lý thay đổi tín hiệu

Các tín hiệu như Instance.ChildAdded/Instance.ChildRemoved và các tín hiệu CollectionService như GetInstanceAddedSignal() hoặc GetInstanceRemovedSignal() cũng phát ra khi phát vào/ra, không thể phân biệt với các lần sinh/xóa thực sự. Các kịch bản nhận không thể phân biệt sự khác biệt chỉ từ tín hiệu, vì vậy logic giả định một tín hiệu tương ứng với một sự kiện "thực" cần được cập nhật.

Kiểm tra các kịch bản cho bất kỳ trình lắng nghe tín hiệu nào có thể bị hỏng hoặc thay đổi đáng kể khi được kích hoạt bởi phát vào và/hoặc phát ra. Ví dụ, nếu bạn phát âm thanh hoặc hiệu ứng hình ảnh khi một NPC kẻ thù lần đầu tiên xuất hiện vào thế giới, hãy gán mỗi kẻ thù một thuộc tính như Spawned khi lần sinh đầu tiên, và bỏ qua việc phát lại âm thanh/hiệu ứng tương tự trong các lần phát vào tương lai của kẻ thù.

Theo dõi thuộc tính
local CollectionService = game:GetService("CollectionService")
local TAG_NAME = "Enemy"
CollectionService:GetInstanceAddedSignal(TAG_NAME):Connect(function(enemy)
if not enemy:GetAttribute("Spawned") then
-- Đặt thuộc tính "Spawned" trên kẻ thù cho lần sinh đầu tiên
enemy:SetAttribute("Spawned", true)
-- Phát âm thanh/hiệu ứng hình ảnh cho lần sinh đầu tiên này
playSpawnEffects(enemy)
end
end)

Lặp qua các bộ sưu tập

Các lần lặp qua bộ sưu tập phía khách hàng như Instance:GetChildren() và Instance:GetDescendants() chỉ trả về tập hợp con đã được phát vào. Điều này áp dụng ngay cả khi cha của nó luôn được sao chép, chẳng hạn như một Folder trực tiếp dưới Workspace mà các thể hiện không gian của nó phát vào và ra.

local Players = game:GetService("Players")
local player = Players.LocalPlayer
-- Thư mục "Homes" luôn được sao chép nhưng các con của nó phát vào và ra
-- Vòng lặp này có thể bỏ lỡ các ngôi nhà không được phát vào hiện tại
for _, home in workspace.Homes:GetChildren() do
if home.Settings.Owner.Value == player.Name then
return home
end
end

Nếu cần một sự liệt kê hoàn chỉnh, hãy thực hiện quét trên máy chủ và truyền kết quả cho người chơi thông qua một RemoteEvent nếu cần.

Các truy vấn không gian

Các truy vấn không gian phía khách hàng như WorldRoot:Raycast(), WorldRoot:GetPartBoundsInBox(), và Model:GetBoundingBox() chỉ phản ánh nội dung đã được phát vào. Việc đó có phải là một vấn đề hay không phụ thuộc vào mục đích sử dụng của truy vấn.

Sử dụng máy chủ cho các truy vấn mà kết quả của nó phải phản ánh toàn bộ thế giới, ví dụ như một raycast kiểm tra xem người chơi có tầm nhìn đến một mục tiêu xa hay không.

Các mẫu khác

Các mẫu sau đây cũng có thể áp dụng và nên được xem xét cẩn thận:

  • Một Sound hoặc AudioPlayer được gán cho một đối tượng 3D sẽ dừng lại khi đối tượng đó phát ra. Đối với âm thanh môi trường nên tồn tại bất kể phát trực tuyến, hãy gán bộ phát cho một mô hình bền vững hoặc cho một bộ chứa không phát trực tuyến.

  • Các đối tượng UI trong trò chơi như BillboardGui hoặc SurfaceGui cũng như các hiệu ứng hình ảnh như Beams hoặc Highlights mà đối tượng hoặc gắn kết của chúng phát ra sẽ ngừng hiển thị. Đây có thể là hành vi mong muốn, nhưng bạn nên xác minh điều này.

  • Các sự kiện BasePart.Touched, ProximityPrompts, DragDetectors, và ClickDetectors không hoạt động cho người chơi mà khách hàng của họ không có phần/mô hình liên quan được phát vào. Nếu tương tác phải có thể từ bất kỳ khoảng cách nào, mô hình cần phải bền vững hoặc tương tác cần một cơ chế khác.

  • Đối với PathfindingService và tìm đường phía khách hàng, bộ tìm đường chỉ thấy hình học đã được phát vào trên khách hàng và nó có thể đi qua các chướng ngại vật tồn tại trên máy chủ. Để biết các chiến lược, xem Tìm đường - Chiến lược cho các chiến lược.

Điều kiện kiểm tra thực tế

Khi các kịch bản đã được cập nhật, hãy kiểm tra trò chơi một cách kỹ lưỡng. Các lỗi phát trực tuyến thường chỉ xuất hiện ở các rìa của khu vực phát trực tuyến hoặc trong các chuyển tiếp, vì vậy chỉ kiểm tra gần điểm sinh hoặc tại bán kính mục tiêu là không đủ.

  • Kiểm tra với Workspace.StreamingTargetRadius được đặt thành giá trị tối thiểu của nó (64). Một số lỗi phát trực tuyến chỉ xuất hiện khi khu vực phát trực tuyến nhỏ.

  • Chơi qua các mẫu di chuyển đầy đủ của trò chơi, dịch chuyển giữa các khu vực xa, và quay lại các khu vực sau khi rời khỏi chúng. Đây là những tình huống mà phát vào và phát ra được thực hiện nhiều nhất.

  • Sử dụng lớp phủ gỡ lỗi phát trực tuyến để theo dõi các cài đặt phát trực tuyến đang hoạt động, các khu vực hiện đang được tải và trạng thái phát trực tuyến trong thời gian chạy.

  • Theo dõi cửa sổ Output và Developer Console để tìm lỗi, vì nhiều mẫu kịch bản tạo ra lỗi thay vì hành vi im lặng sai lệch. Chú ý đặc biệt đến các lỗi có dạng attempt to index nil with ... thường chỉ ra một cuộc gọi WaitForChild() bị thiếu.

  • Trang bị và kích hoạt Tools, bắn vũ khí và kích hoạt các tương tác trò chơi khác.

Kỹ năng chuyển đổi phát trực tuyến AI

Để hỗ trợ với việc chuyển đổi và tối ưu hóa phát trực tuyến, Roblox cung cấp một kỹ năng phát trực tuyến AI, có thể truy cập từ máy chủ MCP trong Studio. Kỹ năng này tự động đánh giá trò chơi của bạn, áp dụng các cấu hình được khuyến nghị và dọn dẹp các vấn đề tương thích, bao gồm:


Để sử dụng kỹ năng AI trong trò chơi của bạn:

  1. QUAN TRỌNG
    Sao lưu trò chơi của bạn. Quá trình chuyển đổi có thể phức tạp, vì vậy bạn nên luôn lưu một bản sao lưu (Tệp ⟩ Xuất bản đến Roblox Như) trước khi chạy kỹ năng.

  2. Bạn có thể chạy kỹ năng này bằng bất kỳ LLM nào bạn thích thông qua Giao thức Ngữ cảnh Mô hình (MCP) trong Studio. Các mô hình AI cao cấp với các cửa sổ ngữ cảnh lớn được khuyến nghị; trong Claude Opus, quá trình chuyển đổi điển hình mất 20-30 phút và sử dụng khoảng 200.000 token ngữ cảnh.

    1. Mở trò chơi của bạn trong Studio.
    2. Tải xuống kỹ năng và, trong khách hàng AI của bạn, mở thư mục đã giải nén (roblox-streaming-conversion) như là dự án hiện tại.
    3. Chạy kỹ năng với /rbx-convert-to-streaming.
    4. Như với bất kỳ đầu ra AI nào, hãy xác minh kết quả và thử nghiệm trò chơi của bạn một cách kỹ lưỡng dưới các điều kiện kiểm tra thực tế.
©2026 Roblox Corporation. Roblox, logo Roblox và Powering Imagination là các nhãn hiệu đã đăng ký và chưa đăng ký của chúng tôi tại Hoa Kỳ và các quốc gia khác.