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 實例以自定義消息外觀。 |
| 禁用聊天 | ChatWindow/ChatSettings 模塊以隱藏聊天窗口 | ChatWindowConfiguration.Enabled |
消息過濾
TextChatService 自動根據每個玩家的帳戶信息過濾聊天消息,因此您無需手動實現所有類型聊天消息的文本過濾。
| 功能 | 舊版聊天 | TextChatService |
|---|---|---|
| 為單個玩家過濾聊天消息 | Chat:FilterStringAsync() | 自動 |
| 過濾廣播消息 | Chat:FilterStringForBroadcast() | 自動 |
窗口和氣泡聊天
TextChatService 的 聊天窗口 和 氣泡聊天 行為和自定義選項與舊版聊天系統相同。由於舊版聊天系統僅允許使用聊天模塊或 Players 容器進行自定義,因此該服務提供專門的類(ChatWindowConfiguration 和 BubbleChatConfiguration)來管理所有聊天窗口和氣泡聊天屬性。此外,您可以輕鬆調整和預覽氣泡聊天的外觀和行為屬性,使用 Studio 設置,而無需編寫所有腳本。
遷移說話者的 "額外數據"
舊版 Lua 聊天系統允許開發者在 Speaker 類上使用 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 使用豐富文本自定義消息的外觀。
以下是通過訪問 Player 對象上的屬性來模擬舊版 Lua 聊天的 "額外數據" 的示例:
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 回調根據設置在玩家上的屬性自定義聊天窗口的外觀:
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