EDITED 12/29/23
I decided to recode the entire system. It still works exactly like it did before, but more performant. I’ve upgraded my programming skills. Let me know if anything needs improved.
Before using this, as I said last time. This should still be used with caution. People on Roblox can say whatever they want, whenever they want. And the ban/VC Suspension/Warning isn’t instant! Depending on the game, if you care about the safety of your player base. Don’t use this. It’s a massive safety hazard.
If you want more features. I sort of suggest AsyncMatrix’s VoicechatSDK. I say “sort of” since
- It hasn’t been updated in a year.
- From when I was using it, for use in a game, it seemed to have problems actually running certain functions the first time. It seemed to have worked if I ran a function not needed once the player joined the game.
Noob version (Explains everything)
--// Variables
local player = game.Players.LocalPlayer --// Get's the LocalPlayer (User running the script)
local RS = game:GetService("RunService")
--// Setting up Fake Character
local Char = Instance.new("Model") --// Create a model to act as our character.
Char.Name = "GlobalVCRoute" --// Name our new Fake Character.
local Humanoid = Instance.new("Humanoid",Char) --// To have it act as a character we need a fake controller.
local Root = Instance.new("Part",Char) --// Here's a Root for our controller.
Root.Name = "HumanoidRootPart" --// This isn't needed but Humanoid usually hooks on to this name.
Char.PrimaryPart = Root --// This just sets the Root as the main part for the controller.
--// Setup for players currently in the server
function SetupPlayer(v:Player)
--// Anti-Old
if v:FindFirstChild("GlobalVCRoute") then v:FindFirstChild("GlobalVCRoute"):Destroy() end --// If they already have a VCModel then delete it, we'll recreate it below.
RS:UnbindFromRenderStep(v.UserId.."_RunFakeCharacter") --// Ensure there is not a BindToRender already. If so, let's just kill it.
--// Setup Fake Character for Use
local Chara = Char:Clone() --// Clone our Fake Character
Chara.Name = v.UserId --// Set it's name to our players userid, so we can find it easily.
Chara.Parent = v
--// Binding to Camera Render
RS:BindToRenderStep(v.UserId.."_RunFakeCharacter",Enum.RenderPriority.Camera,function() --// Create a loop that runs every camera tick. We can unbind it later once the player leaves to save performance.
if Chara ~= nil then --// Check if our VCRoute exists (Anti-error activity)
Chara:WaitForChild("HumanoidRootPart").CFrame = game.Workspace.CurrentCamera.CFrame --// Set the Root of our Fake Character, that acts like the VC player, to our Camera CFrame.
else
RS:UnbindFromRenderStep(v.UserId.."_RunFakeCharacter") --// If our VCRoute get's deleted unexpectly, we won't want this stuck on.
end
end)
--// Assigning
v.Character = Chara --// Set the players fake character.
v.CharacterAdded:Connect(function(char) --// Run every time the player spawns in
v.Character = Chara --// Set the players fake character every time they spawn in.
end)
end
for i,v in pairs(game.Players:GetChildren()) do --// Loop through every player already in the game once
if v ~= player then --// Block the LocalPlayer
SetupPlayer(v) --// We will use our function above to set them up.
end
end
--// Setup new Players
game.Players.PlayerAdded:Connect(function(plr) --// Detect when a new player joins the game.
SetupPlayer(plr) --// We will use our function above to set them up.
end)
--// Detect leaving players
game.Players.PlayerRemoving:Connect(function(plr) --// Detect when a player, already in the server, is leaving.
RS:UnbindFromRenderStep(plr.UserId.."_RunFakeCharacter") --// Let's unbind our loop to save memory.
end)
Gamer version (No Annoying notes)
--// Variables
local player = game.Players.LocalPlayer
local RS = game:GetService("RunService")
--// Setting up Fake Character
local Char = Instance.new("Model")
Char.Name = "GlobalVCRoute"
local Humanoid = Instance.new("Humanoid",Char)
local Root = Instance.new("Part",Char)
Root.Name = "HumanoidRootPart"
Char.PrimaryPart = Root
--// Setup for players currently in the server
function SetupPlayer(v:Player)
--// Anti-Old
if v:FindFirstChild("GlobalVCRoute") then v:FindFirstChild("GlobalVCRoute"):Destroy() end
RS:UnbindFromRenderStep(v.UserId.."_RunFakeCharacter")
--// Setup Fake Character for Use
local Chara = Char:Clone()
Chara.Name = v.UserId
Chara.Parent = v
--// Binding to Camera Render
RS:BindToRenderStep(v.UserId.."_RunFakeCharacter",Enum.RenderPriority.Camera,function()
if Chara ~= nil then
Chara:WaitForChild("HumanoidRootPart").CFrame = game.Workspace.CurrentCamera.CFrame
else
RS:UnbindFromRenderStep(v.UserId.."_RunFakeCharacter")
end
end)
--// Assigning
v.Character = Chara
v.CharacterAdded:Connect(function(char)
v.Character = Chara
end)
end
for i,v in pairs(game.Players:GetChildren()) do
if v ~= player then
SetupPlayer(v)
end
end
--// Setup new Players
game.Players.PlayerAdded:Connect(function(plr)
SetupPlayer(plr)
end)
--// Detect leaving players
game.Players.PlayerRemoving:Connect(function(plr)
RS:UnbindFromRenderStep(plr.UserId.."_RunFakeCharacter")
end)
accidentallyposteditinchatinsteadofeditingsonowihavetoputthissoicanevenpostitahhhhh