傳統聊天系統

*此內容是使用 AI(Beta 測試版)翻譯,可能含有錯誤。若要以英文檢視此頁面,請按一下這裡

階級

傳統聊天系統使用 客戶端-伺服器模型 。 服務器側聊天模組零件 聊天채널 和 聊天講師 管理由 2>聊天服務2> 處理,而客戶端負責輸入和顯示訊息。 與客戶端通信是自動使用 <

Class.Chat 引擎服務本身是聊天系統的必需存儲單位:當 Roblox 位置載入 (在客戶端或 Studio 執行或播放時) 時,以下部分將自動載入到 Chat 服務,如果 Chat.LoadDefaultChat 是真的。

  • 聊天模組 — 此 Folder 是由 聊天服務執行器 所需的模組的收集。 所有此文件夾的內容都是由腳本所需的,並且用於在服務伺服器上創建自訂行為。
  • ClientChatModule — 此資料夾包含 ChatScript 所需的各種 ModuleScripts
    • 指令模組 — 包含用於實現客戶端聊天指令的模組。
    • MessageCreatorModule — 包含處理和格式化訊息的模組。
    • 聊天指令 — 包含伺服器和客戶端共享的常量。
    • ChatSettings — 保存各種設定來配置 聊天視窗 的不同部分。
  • 聊天本地化 — 資料結構,可以儲存文字翻譯。
  • ChatServiceRunner — 此 Script 執行聊天室的服務器部分。 一般來說,這不需要修改來創建自訂聊天行為和功能。
  • 泡泡聊天 — 顯示使用者聊天訊息在遊戲中的頭銜 (如果啟用)。
  • ChatScript — 此 LocalScript 執行聊天室的客戶端部分。 與 ChatServiceRunner 一樣,這應該不需要修改來自聊天室的自訂。 當遊戲執行此操作時,它會自動複製到 StarterPlayerScripts

修改聊天系統

若要修改或自訂傳統聊天系統,您必須先複製上方的階層。

  1. Explorer 窗口中,找到 TextChatService 。然後在 屬性 窗口中設置 1>聊天版本1> 屬性為 4>LegacyChatService4> 。

  2. 使用 播放 按鈕 ( F5 ) 來執行體驗。

  3. 選擇並複製 ( CtrlCC ) 添加到 2>Class.Chat2> 的對象。

  4. 使用 停止 按鈕 ( ShiftF5 ) 來停止體驗。

  5. 選擇 Chat貼入到 ( Ctrl 0> Shift0> 2> V2> 或 5> ⌘5> 7> Shift7> 9> V9>) 複製的對象 (必須與 2>

  6. 確認 Chat.LoadDefaultChat 已啟用。

聊天工作流程

在製作模組來自訂聊天時,重要的是要了解聊天訊息的工作流程。 以發送文字訊息的方式,聊天系統中有各種命令,因此每個訊息都必須檢查,以確認它們是否需要解釋為指令或只是一個文字訊息。 甚至是文字訊息也可以在過程中修改和過濾。

一旦使用者在聊天輸入中專注並輸入角色,就會在客戶端上進行一些檢查。如果角色是 Esc,輸入框會關閉,沒有任何操作發生。如

聊天的客戶端有兩種處理器:進行中已完成。前者評估每個角色被輸入後,而後者評估只是當使用者完成輸入後並達到Enter

當使用者完成輸入並點擊 輸入 時,他們的輸入通過多個命令處理器傳送。如果 進行中 指令製造了自訂聊天狀態,聊天檢查狀態來確認是否要執行最後一個指令

當訊息到達服務伺服器時,它會通過另一個命令處理器。 就像 已完成 處理器在客戶端上,如果任何此處理器返回真,則訊息停止執行。 否則,訊息通過一系列過濾器(包括預設 Roblox 聊天過濾器)傳送到所有通道並合適的喇叭。 一旦這一切都完成,訊

服務器模組

將模組放入 聊天模組 可以用於各種目的。這些模組可以用來管理聊天頻道和講師、添加過濾和命令功能、執行聊天機器人或其他需要處理在服務伺服器上的任何內容。要與聊天系統交互,每個模組都會傳送一個 ChatService 物件。

ChatServiceRunner 開始時,它需要在 ChatModule 內的每個模組。它期望每個模組都會返回一個函數,然後將其 ChatService 對象傳送給每個模組。無論模組的目的是什麼 (執行機器人、添加過濾器功能等),它都需要跟隨此形式才能運行。

範例模組框架

local function Run(ChatService)
-- 代碼在這裡
end
return Run

添加頻道

聊天模組 可以做的最簡單的事情是管理 頻道 。頻道對象可以使用 AddChannel() 方法的 1>ChatService1> 來創建。當參考 4>聊天服務4> 或


local function Run(ChatService)
local myChannel = ChatService:AddChannel("MyChannel")
end
return Run

基本頻道設定

頻道有多個可以用來稍微修改它們的屬性。例如,此模組會創建一個頻道,並設置歡迎訊息,讓用戶自動加入頻道,當他們進入體驗。


local function Run(ChatService)
local myChannel = ChatService:AddChannel("MyChannel")
-- 設定使用者加入頻道時顯示的訊息
myChannel.WelcomeMessage = "Welcome to my channel!"
-- 讓玩家在進入遊戲時自動加入頻道
myChannel.AutoJoin = true
end
return Run

通道事件

頻道有多個事件可以訂閱。這些事件會在發送 聊天訊息 到頻道時發生,當 聊天講師 離開或加入時,或當 MyChannel 被靜音或解靜。例如,此模組會創建一個


local function Run(ChatService)
local myChannel = ChatService:AddChannel("MyChannel")
local function onSpeakerJoined(speakerName)
myChannel:SendSystemMessage(speakerName .. " has joined the channel.")
end
local function onSpeakerLeft(speakerName)
myChannel:SendSystemMessage(speakerName .. " has left the channel.")
end
myChannel.SpeakerJoined:Connect(onSpeakerJoined)
myChannel.SpeakerLeft:Connect(onSpeakerLeft)
end
return Run

指令功能

另一個強大的事件,ChatModule 可以執行的是聊天 指令 。當發送訊息到服務器時,聊

指令功能通常用於實現 管理員指令,這是一些用戶可以使用來操作體驗狀態的特定文字指令。

在這個例子中, 聊天模組 用來創建 Part 如果使用者在聊天中輸入 /part 。注意,此功能會返回 true 如果零件被創建,這將會停止訊息的傳輸,並且顯示沒有訊息。如果零件未被創建,此功能將需要返回 false 以便系統能�


local function Run(ChatService)
local function createPart(speakerName, message, channelName)
if string.sub(message, 1, 5) == "/part" then
local newPart = Instance.new("Part")
newPart.Parent = workspace
return true
end
return false
end
ChatService:RegisterProcessCommandsFunction("createPart", createPart)
end
return Run

Chat 聊天頻道 和 聊天服務 本身都可以有聊天指令。 聊天服務 指令處理器將在每個發送到服務伺服器的訊息上執行,而且頻道指令將只在 2>聊天頻道2> 上執行。

過濾功能

未被 命令功能 停止的訊息將穿過所有 聊天服務 和相關頻道註冊的過濾功能。 每個過濾功能都會傳送給發言人,訊息物件和頻道名稱。 任何對訊息對象所做的變更都會持續,每個過濾功能的下一個將看到更新的訊息。 注意過��

在這個範例中,一個簡單的過濾功能已註冊,以便每個訊息都以下帶頭顯示。


local function Run(ChatService)
local function makeLowercase(sender, messageObject, channelName)
messageObject.Message = string.lower(messageObject.Message)
end
ChatService:RegisterFilterMessageFunction("makeLowercase", makeLowercase)
end
return Run

客戶模組

將模組放入 ClientChatModule 可以為客戶提供自訂行為。這些模組分為兩個不同的文件夾: 指令模組訊息創建器模組

指揮模組

指令模塊 工作很像在服務器上註冊的模組 指令功能 。這些模塊定義會在用戶輸入文字後發射的指訊息。這個文字可以被閱取,命令可以通過服務器發射消息或

在兩種類型的指令中,模組必須返回一個典型的指令,說明程式碼應該使用哪一種處理器,並且在處理器被稱為時執行哪一個功能。例如,一個 完成的訊息處理器 必須以下形式取得:


local util = require(script.Parent:WaitForChild("Util"))
function ProcessMessage(message, ChatWindow, ChatSettings)
end
return {
[util.KEY_COMMAND_PROCESSOR_TYPE] = util.COMPLETED_MESSAGE_PROCESSOR,
[util.KEY_PROCESSOR_FUNCTION] = ProcessMessage
}

注意,KEY_COMMAND_PROCESSOR_TYPE 枚數定義在 Util ModuleScript 內的 1>CommandModuleScript1> 子目錄內。

已完成訊息指令

已完成訊息指令 會在使用者完成輸入後評估。 處理器的函數是通過 Enter 對話物件、客戶伺服器的 聊天窗口 和 0>聊天設定0> 桌子來傳送訊息的。

舉例來說,下列處理器將會移除目前頻道中最舊的訊息,如果使用者輸入指令 /last


local util = require(script.Parent:WaitForChild("Util"))
function ProcessMessage(message, ChatWindow, ChatSettings)
if string.sub(message, 1, 5) == "/last" then
local currentChannel = ChatWindow:GetCurrentChannel()
if currentChannel then
currentChannel:RemoveLastMessageFromChannel()
end
return true
end
return false
end
return {
[util.KEY_COMMAND_PROCESSOR_TYPE] = util.COMPLETED_MESSAGE_PROCESSOR,
[util.KEY_PROCESSOR_FUNCTION] = ProcessMessage
}

進行中指令

進行中指令 每次使用者在聊天輸入框裏輸入角色時評估。例如,下列代碼在每次按鍵壓下後會播放一個敲敲聲,讓它聽起來像使用者正在打字:


local util = require(script.Parent:WaitForChild("Util"))
local keyEffect = Instance.new("Sound")
keyEffect.SoundId = "rbxassetid://12221976"
keyEffect.Parent = script
function ProcessMessage(message, ChatWindow, ChatBar, ChatSettings)
keyEffect:Play()
end
return {
[util.KEY_COMMAND_PROCESSOR_TYPE] = util.IN_PROGRESS_MESSAGE_PROCESSOR,
[util.KEY_PROCESSOR_FUNCTION] = ProcessMessage
}

進行中的指令通常用於在聊天機器人發送訊息給特定用戶而不是僅發送當前頻道。 例如,Whisper和Team Chat系統檢查用戶是否輸入了 /whisper 或 /whisper ,並且發送完成的訊息給只有適當的用戶。

自訂狀態應該包含以下功能:

  • TextUpdated() — 呼叫輸入框中的文字更新時。
  • GetMessage() — 在使用者完成輸入訊息後呼叫 — 按一下 輸入 。 此功能應該會返回一個字串。
  • ProcessCompletedMessage() — 訊息正在處理中。 自訂狀態處理器將在完成訊息處理器之前發射。 像其他處理器一樣,此功能將在訊息停止傳送後返回真。
  • Destroy() — 在訊息已發送後呼叫。應該用於清除由自訂狀態設置的任何東西。

要使用自訂狀態,指令模組的 ProcessMessage() 必須返回狀態。一般來說,自訂狀態的格式如下:


local util = require(script.Parent:WaitForChild("Util"))
local oneLineState = {}
oneLineState.__index = oneLineState
function oneLineState:TextUpdated()
local text = self.TextBox.Text
local length = string.len(text)
if length > 20 then
local chopLength = length - 20
local addToPrefix = string.sub(text, 1, chopLength)
self.Prefix = self.Prefix .. addToPrefix
self.TextBox.Text = string.sub(text, chopLength + 1)
end
end
function oneLineState:GetMessage()
local fullString = self.Prefix .. self.TextBox.Text
return fullString
end
function oneLineState:ProcessCompletedMessage()
return false
end
function oneLineState:Destroy()
self.Destroyed = true
end
function oneLineState.new(ChatWindow, ChatBar, ChatSettings)
local obj = {}
setmetatable(obj, oneLineState)
obj.Destroyed = false
obj.ChatWindow = ChatWindow
obj.ChatBar = ChatBar
obj.ChatSettings = ChatSettings
obj.TextBox = ChatBar:GetTextBox()
obj.MessageModeLabel = ChatBar:GetMessageModeTextLabel()
obj.Prefix = ""
return obj
end
local function ProcessMessage(message, ChatWindow, ChatBar, ChatSettings)
return oneLineState.new(ChatWindow, ChatBar, ChatSettings)
end
return {
[util.KEY_COMMAND_PROCESSOR_TYPE] = util.IN_PROGRESS_MESSAGE_PROCESSOR,
[util.KEY_PROCESSOR_FUNCTION] = ProcessMessage
}

使用自訂狀態的主要優點之一是,模組可以編輯聊天欄和其內容的文字,而且用戶正在輸入功能和外觀方面都可以自由設定,然後稍後重設它(一旦發送一個訊息,即會自動移除並重設為預設值)。 為了


local util = require(script.Parent:WaitForChild("Util"))
local oneLineState = {}
oneLineState.__index = oneLineState
function oneLineState:TextUpdated()
local text = self.TextBox.Text
local length = string.len(text)
if length > 20 then
local chopLength = length - 20
local addToPrefix = string.sub(text, 1, chopLength)
self.Prefix = self.Prefix .. addToPrefix
self.TextBox.Text = string.sub(text, chopLength + 1)
end
end
function oneLineState:GetMessage()
local fullString = self.Prefix .. self.TextBox.Text
return fullString
end
function oneLineState:ProcessCompletedMessage()
return false
end
function oneLineState:Destroy()
self.Destroyed = true
end
function oneLineState.new(ChatWindow, ChatBar, ChatSettings)
local obj = {}
setmetatable(obj, oneLineState)
obj.Destroyed = false
obj.ChatWindow = ChatWindow
obj.ChatBar = ChatBar
obj.ChatSettings = ChatSettings
obj.TextBox = ChatBar:GetTextBox()
obj.MessageModeLabel = ChatBar:GetMessageModeTextLabel()
obj.Prefix = ""
return obj
end
local function ProcessMessage(message, ChatWindow, ChatBar, ChatSettings)
return oneLineState.new(ChatWindow, ChatBar, ChatSettings)
end
return {
[util.KEY_COMMAND_PROCESSOR_TYPE] = util.IN_PROGRESS_MESSAGE_PROCESSOR,
[util.KEY_PROCESSOR_FUNCTION] = ProcessMessage
}

如前所述,一旦發送任何訊息,任何自訂狀態都會被移除,聊天室將恢復正常。如果需要重設自訂狀態,請使用 ChatBar:ResetCustomState() 來重設。注意,這會從聊天欄中移除對話框的焦點。

訊息創建模組

客戶端零件中使用的另一種模組是 訊息創建器 模組。這種模組是用於在聊天窗口中顯示訊息的 GUI 元素的。每種訊息創建器都定義一種新的訊息類輸入,因此不同類型的訊息可以用不同的格式來顯示訊息。此外, GUI 元素可以添加到顯示訊息的方式,這允許添加圖像、按��

這些模組需要在多個不同的位置設置。對於每種訊息類輸入,必須在 ModuleScript 內有一個 Class.ModuleScript 。此外, 聊天 чат模組 內必須編輯 2>Class.ModuleScript2> 以包含新的訊息輸入輸入。最後,模組只有在服務器的聊天部分��

下面的例子會通過建立每 5 秒說時間的機器人,以及發送的訊息獲得紅色背景。

要啟動, ChatSuppress ModuleScript 需要添加一個新類型的訊息的字段。


-- 聊天常量
local module = {}
------訊息類型
module.MessageTypeDefault = "Message"
module.MessageTypeSystem = "System"
module.MessageTypeMeCommand = "MeCommand"
module.MessageTypeWelcome = "Welcome"
module.MessageTypeSetCore = "SetCore"
module.MessageTypeWhisper = "Whisper"
module.MessageTypeTime = "Time"
module.MajorVersion = 0
module.MinorVersion = 2
return module

機器人本身在服務伺服器上建立了一個新的 聊天模組 。注意,過濾功能是用於將新的訊息類型添加到機器人發送的訊息。


-- ChatModule 的新模組脚本
local Chat = game:GetService("Chat")
local ReplicatedModules = Chat:WaitForChild("ClientChatModules")
local ChatConstants = require(ReplicatedModules:WaitForChild("ChatConstants"))
local function Run(ChatService)
local timeBot = ChatService:AddSpeaker("TimeBot")
timeBot:JoinChannel("All")
local function addMessageType(speaker, messageObject, channelName)
if speaker == "TimeBot" then
messageObject.MessageType = ChatConstants.MessageTypeTime
end
end
ChatService:RegisterFilterMessageFunction("TimeBotFilter", addMessageType)
task.spawn(function()
while task.wait(5) do
timeBot:SayMessage("The current time is: " .. os.time(), "All", {})
end
end)
end
return Run

最後,必須要做一個訊息創建模組。這個模組必須返回一個字典,其中包含兩個元素:訊息的類型,索引為 KEY_MESSAGE_TYPE ,以及創建訊息 GUI 元素時所需的函數: KEY_CREATOR_FUNCTION

KEY_CREATOR_FUNCTION 的功能需要返回包含多個元素的字典。首先,它需


-- 新ModuleScript 要被包含在 MessageCreatorModule 中
local messageCreatorModules = script.Parent
local util = require(messageCreatorModules:WaitForChild("Util"))
local clientChatModules = messageCreatorModules.Parent
local ChatSettings = require(clientChatModules:WaitForChild("ChatSettings"))
local ChatConstants = require(clientChatModules:WaitForChild("ChatConstants"))
local function CreateMessageLabel(messageData, channelName)
-- 創建枕頭和標籤以傳送訊息
local BaseFrame, BaseMessage = util:CreateBaseMessage("", ChatSettings.DefaultFont, ChatSettings.ChatWindowTextSize, ChatSettings.DefaultMessageColor)
-- 將框架的背景變更為紅色
BaseFrame.BackgroundColor3 = Color3.new(1,0,0)
BaseFrame.BackgroundTransparency = 0
-- 處理更新預覽訊息文字
local function UpdateTextFunction(messageObject)
if messageObject.IsFiltered then
BaseMessage.Text = messageObject.Message
end
end
UpdateTextFunction(messageData)
-- 使用 util 函數來確定框架的高度
local function GetHeightFunction(xSize)
return util:GetMessageHeight(BaseMessage, BaseFrame, xSize)
end
-- 創建漸漸消失的功能,當聊天視窗漸漸消失時呼叫
local FadeParameters = {}
FadeParameters[BaseMessage] = {
TextTransparency = {FadedIn = 0, FadedOut = 1},
TextStrokeTransparency = {FadedIn = 0.75, FadedOut = 1}
}
local FadeInFunction, FadeOutFunction, UpdateAnimFunction = util:CreateFadeFunctions(FadeParameters)
-- 返回定義訊息標籤的典型資料庫
return {
[util.KEY_BASE_FRAME] = BaseFrame,
[util.KEY_BASE_MESSAGE] = BaseMessage,
[util.KEY_UPDATE_TEXT_FUNC] = UpdateTextFunction,
[util.KEY_GET_HEIGHT] = GetHeightFunction,
[util.KEY_FADE_IN] = FadeInFunction,
[util.KEY_FADE_OUT] = FadeOutFunction,
[util.KEY_UPDATE_ANIMATION] = UpdateAnimFunction
}
end
return {
[util.KEY_MESSAGE_TYPE] = ChatConstants.MessageTypeTime,
[util.KEY_CREATOR_FUNCTION] = CreateMessageLabel
}