语音聊天是一种基于距离的聊天功能,通过调整玩家之间说话音量,使他们在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 = "红队"local blueTeam = Instance.new("Team", Teams)blueTeam.TeamColor = BrickColor.new("Bright blue")blueTeam.AutoAssignable = trueblueTeam.Name = "蓝队"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 属性设置为 允许,以便每个团队中的 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 键设置为玩家需要按住的按钮,以便对麦克风说话。
- 将玩家的麦克风静音。
剩下的脚本为 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秒的时间间隔内通过语音聊天只能听到彼此。