语音聊天是一种基于接近的聊天功能,通过调整玩家在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 - 返回团队中所有玩家的用户ID数组。
- updateTeam - 从 getUserIds 获取所有用户ID,遍历 getDevices 中的 AudioDeviceInput 对象,将它们的 Enum.AccessModifierType 属性设置为 Allow,以便只有每个团队中的用户ID被允许听到其队友的麦克风,然后使用团队中的用户ID更新 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 键设置为玩家需要按住的按钮,以便通过麦克风说话。
- 将玩家的麦克风静音。
脚本的其余部分为 UserInputService 设置了两个事件监听器,分别用于 InputBegan 和 InputEnded。当他们按下 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秒的时间段内通过语音聊天听到彼此。