語音聊天是一種基於距離的聊天功能,通過調整玩家在3D空間中彼此靠近或遠離時的音量,模擬現實的交流。通過讓玩家使用他們的麥克風進行對話,他們能夠在全球範圍內實時社交和協作,以完成您遊戲的目標。
使用 Gingerbread Island - Voice Chat .rbxl 文件作為參考,本教程將向您展示如何將不同形式的語音聊天整合到您的遊戲中,包括以下指導:
- 將玩家分組到只能與隊友使用語音聊天的隊伍中。
- 允許玩家在按下設備上的特定按鈕時暫時啟用他們的麥克風。
- 配置語音聊天啟用或禁用的時間段。
在您查看以下部分的同時,您可以根據自己的語音聊天需求調整每個代碼示例。
配置設置
為了使隊伍聊天、按鍵聊天或基於時間的聊天正常工作,您必須 配置您的語音聊天設置,以啟用語音聊天並創建在3D環境中接收和發出音頻所需的適當音頻對象。
當玩家加入您的遊戲時,您的語音聊天設置現在:
- 允許符合語音聊天條件的玩家使用他們的麥克風。
- 在每個符合語音聊天條件的 Player 對象下創建並父級化一個 AudioDeviceInput 對象。
- 在每個符合語音聊天條件的 Player.Character 下創建並父級化一個 AudioEmitter 對象。
- 在 Workspace.CurrentCamera 下創建並父級化一個 AudioListener。
以下部分詳細介紹了使用這些設置的三種獨特語音聊天配置。當您跟隨示例 Gingerbread Island - Voice Chat 放置文件時,您可以在 Explorer 窗口中啟用相應的禁用腳本以測試其行為。為了確保每個配置正常工作,在進入下一個配置之前,請務必再次禁用該腳本。

添加隊伍聊天
隊伍聊天是一種語音聊天配置,其中只有同一隊伍的玩家可以在遊戲中彼此說話或聽到對方。將隊伍聊天整合到您的遊戲中是有用的,當您希望玩家協作並共同制定策略以解決遊戲中的問題,例如協調敵隊位置、資源和任務的信息。
要在示例 Gingerbread Island - Voice Chat 放置文件中重建隊伍語音聊天:
在 Explorer 窗口中,將 Script 插入到 ServerScriptService 中。
將腳本重命名為 TeamChat,然後將以下代碼粘貼到腳本中:
local Teams = game:GetService("Teams")local Players = game:GetService("Players")local redTeam = Instance.new("Team", Teams)redTeam.TeamColor = BrickColor.new("Bright red")redTeam.AutoAssignable = trueredTeam.Name = "Red Team"local blueTeam = Instance.new("Team", Teams)blueTeam.TeamColor = BrickColor.new("Bright blue")blueTeam.AutoAssignable = trueblueTeam.Name = "Blue Team"local function getUserIds(team : Team) : {number}local userIds = {}for _, player : Player in team:GetPlayers() dotable.insert(userIds, player.UserId)endreturn userIdsendlocal function getDevices(team : Team) : {AudioDeviceInput}local devices = {}for _, player : Player in team:GetPlayers() dolocal device : AudioDeviceInput = player:FindFirstChild("AudioDeviceInput")if not device thencontinueendtable.insert(devices, device)endreturn devicesendlocal function updateTeam(team : Team)local users = getUserIds(team)for _, device in getDevices(team) dodevice.AccessType = Enum.AccessModifierType.Allowdevice:SetUserIdAccessList(users)endendlocal function onDeviceAdded(device : AudioDeviceInput)local player : Player = device.Parentif player.Team thenupdateTeam(player.Team)endendlocal function onPlayerAdded(player : Player)local device = player:FindFirstChild("AudioDeviceInput")if device thenonDeviceAdded(device)endplayer.ChildAdded:Connect(function(child)if child.Name == "AudioDeviceInput" thenonDeviceAdded(child)endend)endupdateTeam(blueTeam)updateTeam(redTeam)for _, player in Players:GetPlayers() doonPlayerAdded(player)endPlayers.PlayerAdded:Connect(onPlayerAdded)blueTeam.PlayerAdded:Connect(function() updateTeam(blueTeam) end)blueTeam.PlayerRemoved:Connect(function() updateTeam(blueTeam) end)redTeam.PlayerAdded:Connect(function() updateTeam(redTeam) end)redTeam.PlayerRemoved:Connect(function() updateTeam(redTeam) end)代碼解釋該腳本首先獲取 Teams 和 Players 服務,以便可以使用它們的現成功能在玩家加入遊戲時將其分組到隊伍中。例如,無需任何額外的腳本工作,Teams 服務處理以下操作:
- 將玩家均勻地分配到每個隊伍中。
- 在排行榜上將玩家分組到他們的隊伍下。
- 將玩家名稱在3D空間中著色為對應的隊伍顏色。
使用此服務,腳本創建了兩個不同的 Team 對象,並為每個隊伍設置不同的 Color 屬性值:一隊為 亮紅色,另一隊為 亮藍色。
然後,腳本定義了三個函數,這些函數是設置隊伍語音聊天配置的主要工作:
- getUserIds - 返回隊伍中所有玩家的 userIDs 陣列。
- updateTeam - 從 getUserIds 獲取所有 userIDs,遍歷 getDevices 中的 AudioDeviceInput 對象,將其 Enum.AccessModifierType 屬性設置為 Allow,以便只有每個隊伍中的 userIDs 被允許聽到其隊友的麥克風,然後使用隊伍中的 userIDs 更新 SetUserIdAccessList。
腳本的其餘部分控制這些函數和事件監聽器如何協同工作:
- 當新玩家加入遊戲時,腳本驗證該玩家是否有麥克風並更新其隊伍。
- 當腳本檢測到新的 AudioDeviceInput 對象時,會為其相應的紅隊或藍隊調用 updateTeam。
- 隨著玩家加入或離開遊戲,腳本連接到 PlayerAdded 和 PlayerRemoved 事件以更新每個隊伍的設置。
與幾位朋友一起進行遊戲測試,以驗證每個隊伍的隊友只能通過語音聊天聽到彼此。
添加按鍵聊天
按鍵聊天是一種語音聊天配置,其中玩家只能在遊戲中按住特定按鈕時啟用他們的麥克風。將按鍵聊天整合到您的遊戲中是有用的,當您希望玩家在想要被其他玩家和環境噪音聽到時擁有更多的隱私和控制權。
要在示例 Gingerbread Island - Voice Chat 放置文件中重建按鍵語音聊天:
在 Explorer 窗口中,將 Script 插入到 ReplicatedStorage 中。
在 Properties 窗口中,將 RunContext 設置為 Client,以便該腳本僅控制本地玩家的麥克風。
將腳本重命名為 PushToChat,然後將以下代碼粘貼到腳本中:
local Players = game:GetService("Players")local UserInputService = game:GetService("UserInputService")local audioIn: AudioDeviceInput = Players.LocalPlayer:WaitForChild("AudioDeviceInput")local pushToTalkKey = Enum.KeyCode.VaudioIn.Muted = trueUserInputService.InputBegan:Connect(function(input: InputObject)if input.KeyCode == pushToTalkKey thenaudioIn.Muted = falseendend)UserInputService.InputEnded:Connect(function(input: InputObject)if input.KeyCode == pushToTalkKey thenaudioIn.Muted = trueendend)代碼解釋該腳本首先獲取:
- Players 服務,以便可以引用遊戲中的所有玩家。
- UserInputService 服務,以便可以檢查玩家何時按下設備上的按鈕。
- 本地玩家的 AudioDeviceInput 對象,即其設備上的物理麥克風。
然後,腳本:
- 將 V 鍵設置為玩家需要按住的按鈕,以便通過麥克風說話。
- 將玩家的麥克風靜音。
腳本的其餘部分設置了兩個事件監聽器,分別用於 InputBegan 和 InputEnded 來自 UserInputService。當他們按下 V 鍵時,InputBegan 事件會取消靜音玩家的麥克風,而當他們釋放 V 鍵時,InputEnded 事件會再次靜音他們的麥克風。
進行遊戲測試,以驗證玩家只有在按下 V 鍵時才能通過語音聊天聽到彼此。
添加基於時間的聊天
基於時間的聊天是一種語音聊天配置,其中玩家只能在設定的時間段內彼此說話和聽到對方。將基於時間的聊天整合到您的遊戲中是有用的,當您希望玩家在特定階段仔細計劃如何與彼此交流,例如在回合討論或過場動畫後。
要在示例 Gingerbread Island - Voice Chat 放置文件中重建基於時間的語音聊天:
在 Explorer 窗口中,將 Script 插入到 ServerScriptService 中。
將腳本重命名為 TimeBasedChat,然後將以下代碼粘貼到腳本中:
local Players = game:GetService("Players")local muteAll = falselocal function toggleMuteAll()muteAll = not muteAllfor _, player in Players:GetPlayers() dolocal device : AudioDeviceInput = player:FindFirstChild("AudioDeviceInput")if not device thencontinueenddevice.Muted = muteAllendendwhile true dotask.wait(15) -- 每15秒toggleMuteAll() -- 允許人們說話或防止他們說話end代碼解釋此腳本首先獲取 Players 服務,以便可以引用其功能來管理遊戲中的所有玩家。然後,它將標誌 muteAll 設置為 false,該標誌在後續的 toggleMuteAll 函數中用於切換語音聊天的開啟和關閉。
讓我們回顧一下 toggleMuteAll 函數:
- 它首先使用 Players.GetPlayers 循環遍歷遊戲中的所有玩家。
- 對於每個玩家,它檢查是否有子 AudioDeviceInput 對象,即其設備上的物理麥克風。
- 如果有,該函數將 AudioDeviceInput 對象的 Muted 屬性設置為 muteAll 的值。例如,如果 muteAll 為 true,則玩家的麥克風被禁用;如果 muteAll 為 false,則玩家的麥克風被啟用。
然後,腳本進入一個無限循環,等待15秒以靜音和取消靜音所有 AudioDeviceInput 對象。
進行遊戲測試,以驗證玩家只能在15秒的增量中通過語音聊天聽到彼此。