Roblox 通過 TextChatService 提供玩家在直播會話中進行文本消息交流,這是一個負責管理整體聊天系統的單例類別,包括聊天消息過濾、管理和用戶權限。該服務具有其標準功能,並提供一組方法和事件,以擴展和自定義聊天,例如根據 自定義要求 傳送消息、為特定玩家添加特殊權限或管理,以及創建 自定義命令 以執行特定操作。
UI 配置
TextChatService 提供了一個可以自定義以適應您遊戲需求的默認 UI。禁用任何這些配置可隱藏其關聯的 UI 元素。如果需要,您也可以用自定義界面替換這些 UI 元素:
通道、消息和命令
TextChannel — 文本通道將用戶發送的消息從客戶端傳遞到服務器,然後根據權限將其顯示給其他用戶。文本通道必須附屬於 TextChatService 才能正常運行。
TextSource — 在 TextChannel 中的用戶。當調用 AddUserAsync() 時,文本源會直接附屬到 TextChannel。文本源包含用戶在通道中的詳細權限,例如他們發送消息的能力。如果單個用戶在多個文本通道中,他們將與多個文本源相關聯。
TextChatMessage — 文本通道中的一條消息。聊天消息包含基本信息,例如消息發送者、原始消息、過濾後的消息以及創建時間戳。
TextChatCommand — 允許用戶通過發送與 PrimaryAlias 或 SecondaryAlias 屬性匹配的消息來觸發特定操作或行為。聊天命令必須附屬於 TextChatService 才能正常運行。
聊天流程圖
文本聊天使用 客戶端‑服務器 模型,包含 發送客戶端、服務器 和 接收客戶端。

玩家從其本地設備發送消息,觸發 TextChannel:SendAsync() 方法。該方法處理消息並確定它是聊天命令還是普通聊天消息。
如果消息是聊天命令,則會觸發 TextChatCommand.Triggered 事件以執行定義的操作。不需要進一步步驟。
如果消息是普通聊天消息,則會觸發 TextChatService.SendingMessage 事件以將消息顯示給發送者。在此同時,TextChannel:SendAsync() 將消息傳遞給服務器。
服務器觸發 TextChannel.ShouldDeliverCallback 以確定是否根據權限和 Roblox 社區過濾要求將消息傳遞給其他玩家。
如果 TextChannel.ShouldDeliverCallback 確定該消息有資格傳送給其他玩家,則服務器將應用任何過濾器並兩次觸發 TextChannel.OnIncomingMessage:
第一次在發送客戶端上,並通過 TextChatService.MessageReceived 事件信號服務器正在處理該消息。此事件用來用服務器處理過的消息替代發送客戶端上的本地消息。如果原始消息不需要過濾,則消息是相同的。
第二次在接收客戶端上,觸發 TextChatService.MessageReceived 事件以將消息顯示給其他玩家。
文本聊天鉤子和回調
TextChatService API 鼓勵在聊天消息的外觀和傳送之間進行明確的區分。文本聊天系統的多個實例提供鉤子和回調,以集中且清晰的方式格式化。

條件傳送消息
TextChannel.ShouldDeliverCallback 回調應僅在服務器上定義。當發送消息時,針對文本通道的每個 TextSource 子項觸發回調,以確定是否應該傳送該消息。這個回調可以用來實現自定義消息傳送邏輯,這可能取決於額外的遊戲上下文,例如:
- 基於距離的聊天,用戶只能向附近的人發送消息。
- 防止具有某些屬性的用戶向其他人發送消息。
自定義消息顯示
默認的 TextChatService UI 依賴 富文本 來格式化和自定義消息的顯示方式。您可以使用以下回調在消息顯示給用戶之前格式化它們,例如添加顏色或 聊天標籤 到用戶名或格式化消息內容。
以下回調會在每個即將顯示的 TextChatMessage 上被調用,這使您能夠根據 TextChannel、TextSource 或 TextChatMessage 內容自定義聊天窗口的外觀。當客戶端發送消息時,這些回調會在消息發送到服務器時調用一次,TextChatMessage.Status 值為 Enum.TextChatMessageStatus.Sending。一旦消息被服務器接收並傳送給其他用戶,發送客戶端再次接收更新的消息,Enum.TextChatMessageStatus 值。
- TextChatService.OnIncomingMessage — 此回調應僅在客戶端上定義。當消息被接收時(無論來自服務器還是本地客戶端剛剛發送的消息)回調被觸發。該回調會在從所有 TextChannel 實例接收到的每個 TextChatMessage 上調用,並且是第一個在消息顯示給用戶之前處理該消息的回調。
- TextChannel.OnIncomingMessage — 此回調應僅在客戶端上定義。當從服務器接收到消息時觸發該回調。該回調會在從 TextChannel 接收到的每個 TextChatMessage 上調用。從 TextChatService.CreateDefaultTextChannels 創建的默認 TextChannel 實例具有此回調定義,並且可以被覆寫。
- TextChatService.OnBubbleAdded — 此回調應僅在客戶端上定義。用於根據消息在聊天窗口 UI 中的外觀自定義聊天氣泡的外觀。
- TextChatService.OnChatWindowAdded — 此回調應僅在客戶端上定義。用於自定義聊天消息在聊天窗口 UI 中的外觀,而不會受氣泡聊天中的消息外觀影響。
從舊版聊天系統遷移
本節通過提供實現常見聊天功能和行為的替代方法來幫助您從舊版聊天系統遷移,使用 TextChatService。
在 Explorer 窗口中,選擇 TextChatService。
在 Properties 窗口中,找到 ChatVersion 下拉菜單並選擇 TextChatService。

基本功能
雖然兩個系統共享相同的基本聊天功能,但 TextChatService 的實現通常更具可持續性且更易於迭代。
| 功能 | 舊版聊天 | TextChatService | 區別 |
|---|---|---|---|
| 發送聊天消息 | Players:Chat() | TextChannel:SendAsync() | SendAsync() 方法支持更高級的聊天功能,例如富文本格式和消息優先級。它還包含內建過濾功能,有助於防止不當消息被發送。 |
| 實現消息回調 | Chat:InvokeChatCallback() Chat:RegisterChatCallback() | TextChatService.SendingMessage TextChatService.OnIncomingMessage | 舊版聊天系統將函數綁定到聊天系統事件以傳遞消息。TextChatService 的這兩個方法提供了更好的靈活性和自定義。 |
| 添加自定義聊天命令 | ChatService/ChatCommand 模塊 | TextChatCommand | TextChatService 擁有專門的類來處理文本命令,而不是使用舊版聊天模塊。 |
| 顯示系統消息 | StarterGui:SetCore() 使用 ChatMakeSystemMessage | TextChannel:DisplaySystemMessage() | TextChannel.OnIncomingMessage 回調可以返回 TextChatMessageProperties 實例以自定義消息外觀。 |
| 禁用聊天 | 體驗設置 在 Studio 和 ChatWindow/ChatSettings 模塊中用於隱藏聊天窗口 | ChatWindowConfiguration.Enabled |
消息過濾
TextChatService 會基於每個玩家的賬號信息自動過濾聊天消息,因此您不需要手動實現所有類型聊天消息的文本過濾。
| 功能 | 舊版聊天 | TextChatService |
|---|---|---|
| 為個別玩家過濾聊天消息 | Chat:FilterStringAsync() | 自動 |
| 過濾廣播消息 | Chat:FilterStringForBroadcast() | 自動 |
窗口和氣泡聊天
TextChatService 的聊天窗口和氣泡聊天行為和自定義選項與舊版聊天系統相同。由於舊版聊天系統僅允許使用聊天模塊或 Players 容器進行自定義,該服務提供專門的類(ChatWindowConfiguration 和 BubbleChatConfiguration)來管理所有聊天窗口和氣泡聊天屬性。此外,您可以輕鬆調整並預覽氣泡聊天的外觀和行為屬性,使用 Studio 設置,而不是必須全部編碼。
遷移說話者 "額外數據"
舊版 Lua 聊天系統允許開發者在 Speaker 類上使用 SetExtraData。這些數據用於格式化名稱顏色、聊天顏色或為給定發言者應用名稱標籤。
舊版聊天系統 SetExtraData
-- 在舊版聊天系統中設置發言者的額外數據的示例
ChatService.SpeakerAdded:Connect(function(playerName)
local speaker = ChatService:GetSpeaker(playerName)
speaker:SetExtraData("NameColor", Color3.fromRGB(255, 255, 55))
speaker:SetExtraData("ChatColor", Color3.fromRGB(212, 175, 55))
speaker:SetExtraData("Tags", {{TagText = "YourTagName", TagColor = Color3.fromRGB(0, 255, 0)}, {TagText = "OtherTagName", TagColor = Color3.fromRGB(255, 0, 0)}})
end)
TextChatService 沒有與 SetExtraData 直接對應的功能。相反,使用 回調 例如 OnWindowAdded 來自定義消息外觀,基於消息的 TextSource 進行富文本格式化。
以下是一個模擬舊版 Lua 聊天 "額外數據" 的示例,通過訪問 Player 對象上的屬性:
TextChatService SetAttributes
local Players = game:GetService("Players")
Players.PlayerAdded:Connect(function(player)
player:SetAttribute("NameColor", Color3.fromRGB(255, 255, 55))
player:SetAttribute("ChatColor", Color3.fromRGB(212, 175, 55))
player:SetAttribute("isYourTag", true)
player:SetAttribute("isOtherTag", true)
end)
然後,您可以使用 OnChatWindowAdded 回調來根據設置在玩家上的屬性自定義聊天窗口的外觀:
TextChatService OnChatWindowAdded
local TextChatService = game:GetService("TextChatService")
local Players = game:GetService("Players")
TextChatService.OnChatWindowAdded = function(textChatMessage)
local textSource = textChatMessage.TextSource
if textSource then
local player = Players:GetPlayerByUserId(textSource.UserId)
if player then
local overrideProperties = TextChatService.ChatWindowConfiguration:DeriveNewMessageProperties()
overrideProperties.PrefixText = textChatMessage.PrefixText
overrideProperties.Text = textChatMessage.Text
local nameColor = player:GetAttribute("NameColor")
if nameColor and typeof(nameColor) == "Color3" then
overrideProperties.PrefixTextProperties.TextColor3 = nameColor
end
local chatColor = player:GetAttribute("ChatColor")
if chatColor and typeof(chatColor) == "Color3" then
overrideProperties.TextColor3 = chatColor
end
local isYourTag = player:GetAttribute("isYourTag")
if isYourTag == true then
overrideProperties.PrefixText = `<font color='rgb(0, 255, 0)'>[YourTag]</font> {overrideProperties.PrefixText}`
end
local isOtherTag = player:GetAttribute("isOtherTag")
if isOtherTag == true then
overrideProperties.PrefixText = `<font color='rgb(255, 0, 0)'>[OtherTag]</font> {overrideProperties.PrefixText}`
end
return overrideProperties
end
end
return nil
end