
Key Required
--============================================================*
-- Prison Life - Persistent ORIGINAL Gun Sounds
--============================================================*
--
-- SHOOTING:
-- • Keeps the original shot playing after weapon switch
-- • One shot = one sound
-- • No double sounds
-- • No looping
--
-- RELOAD:
-- • Keeps the original reload playing after weapon switch
-- • Does not restart
-- • Does not loop
--
-- AUDIO:
-- • Uses the ORIGINAL game's SoundId
-- • Preserves the original sound's 3D position
-- • Does NOT play as a background/global sound
--
--============================================================*
local Players = game:GetService("Players")
local Workspace = game:GetService("Workspace")
local Player = Players.LocalPlayer
--============================================================*
-- PERSISTENT FOLDER
--============================================================*
local PersistentFolder =
Workspace:FindFirstChild("PrisonLife_PersistentGunSounds")
if not PersistentFolder then
PersistentFolder = Instance.new("Folder")
PersistentFolder.Name = "PrisonLife_PersistentGunSounds"
PersistentFolder.Parent = Workspace
end
--============================================================*
-- SOUND DETECTION
--============================================================*
local function getSoundType(sound)
if not sound
or not sound:IsA("Sound")
then
return nil
end
local name =
string.lower(sound.Name)
------------------------------------------------------------
-- RELOAD
------------------------------------------------------------
if string.find(name, "reload", 1, true) then
return "reload"
end
------------------------------------------------------------
-- SHOOTING
------------------------------------------------------------
if string.find(name, "shoot", 1, true) then
return "shoot"
end
if string.find(name, "fire", 1, true) then
return "shoot"
end
if string.find(name, "shot", 1, true) then
return "shoot"
end
return nil
end
--============================================================*
-- TRACKING
--============================================================*
local hooked = {}
local lastPreserved = {}
--============================================================*
-- GET WORLD POSITION
--============================================================*
local function getSoundPosition(sound)
local parent =
sound.Parent
if parent and parent:IsA("Attachment") then
return parent.WorldPosition
end
if parent and parent:IsA("BasePart") then
return parent.Position
end
local part =
sound:FindFirstAncestorWhichIsA("BasePart")
if part then
return part.Position
end
return nil
end
--============================================================*
-- CREATE 3D SOUND CARRIER
--============================================================*
local function createCarrier(position)
if not position then
return nil
end
local carrier =
Instance.new("Part")
carrier.Name =
"PersistentGunSoundEmitter"
carrier.Size =
Vector3.new(0.1, 0.1, 0.1)
carrier.Transparency = 1
carrier.Anchored = true
carrier.CanCollide = false
carrier.CanTouch = false
carrier.CanQuery = false
carrier.CastShadow = false
carrier.CFrame =
CFrame.new(position)
carrier.Parent =
PersistentFolder
return carrier
end
--============================================================*
-- PRESERVE SOUND
--============================================================*
local function preserveSound(sound)
if not sound
or not sound.Parent
or not sound:IsA("Sound")
then
return
end
local soundType =
getSoundType(sound)
if not soundType then
return
end
------------------------------------------------------------
-- Prevent duplicate event handling
------------------------------------------------------------
local now =
os.clock()
if lastPreserved[sound]
and now - lastPreserved[sound] < 0.08
then
return
end
lastPreserved[sound] =
now
------------------------------------------------------------
-- Remember the original world position
------------------------------------------------------------
local position =
getSoundPosition(sound)
------------------------------------------------------------
-- Clone ORIGINAL sound
------------------------------------------------------------
local clone
local success =
pcall(function()
clone =
sound:Clone()
end)
if not success
or not clone
then
return
end
------------------------------------------------------------
-- Never loop
------------------------------------------------------------
clone.Looped =
false
------------------------------------------------------------
-- Create a proper 3D emitter
------------------------------------------------------------
local carrier =
createCarrier(position)
if carrier then
clone.Parent =
carrier
else
-- Fallback if the original sound has no
-- detectable world position.
clone.Parent =
PersistentFolder
end
------------------------------------------------------------
-- Continue from EXACT current playback position
------------------------------------------------------------
pcall(function()
clone.TimePosition =
sound.TimePosition
end)
------------------------------------------------------------
-- Play the persistent copy
------------------------------------------------------------
pcall(function()
clone:Play()
end)
------------------------------------------------------------
-- Stop the original.
--
-- The clone is now independent and survives
-- weapon switching / unequipping.
------------------------------------------------------------
task.defer(function()
if sound
and sound.Parent
then
pcall(function()
sound:Stop()
end)
end
end)
--========================================================*
-- CLEANUP
--========================================================*
local cleaned =
false
local function cleanup()
if cleaned then
return
end
cleaned =
true
pcall(function()
if clone then
clone:Destroy()
end
end)
pcall(function()
if carrier then
carrier:Destroy()
end
end)
end
------------------------------------------------------------
-- Normal sound completion
------------------------------------------------------------
clone.Ended:Connect(function()
cleanup()
end)
------------------------------------------------------------
-- Safety cleanup
------------------------------------------------------------
task.spawn(function()
local startTime =
os.clock()
local length =
0
pcall(function()
length =
clone.TimeLength
end)
if length <= 0 then
task.wait(0.25)
pcall(function()
length =
clone.TimeLength
end)
end
local timeout =
math.max(
length + 1,
5
)
while
not cleaned
and clone
and clone.Parent
and os.clock() - startTime < timeout
do
task.wait(0.1)
end
cleanup()
end)
end
--============================================================*
-- HOOK SOUND
--============================================================*
local function hookSound(sound)
if not sound:IsA("Sound") then
return
end
local soundType =
getSoundType(sound)
if not soundType then
return
end
if hooked[sound] then
return
end
hooked[sound] =
true
------------------------------------------------------------
-- SHOOTING
--
-- ONLY Played is used.
-- This prevents the double-shot problem.
------------------------------------------------------------
if soundType == "shoot" then
sound.Played:Connect(function()
preserveSound(sound)
end)
------------------------------------------------------------
-- RELOAD
------------------------------------------------------------
elseif soundType == "reload" then
sound.Played:Connect(function()
preserveSound(sound)
end)
--------------------------------------------------------
-- Backup for reload sounds that change Playing
-- without properly firing Played.
--------------------------------------------------------
sound:GetPropertyChangedSignal("Playing"):Connect(
function()
if not sound.Playing then
return
end
local now =
os.clock()
if not lastPreserved[sound]
or now - lastPreserved[sound] > 0.08
then
preserveSound(sound)
end
end
)
end
------------------------------------------------------------
-- Cleanup tracking
------------------------------------------------------------
sound.Destroying:Connect(function()
hooked[sound] =
nil
lastPreserved[sound] =
nil
end)
end
--============================================================*
-- SCAN CONTAINER
--============================================================*
local function scanContainer(container)
if not container then
return
end
------------------------------------------------------------
-- Existing sounds
------------------------------------------------------------
for _, object in ipairs(
container:GetDescendants()
) do
if object:IsA("Sound") then
hookSound(object)
end
end
------------------------------------------------------------
-- Newly-created sounds
------------------------------------------------------------
container.DescendantAdded:Connect(
function(object)
if object:IsA("Sound") then
hookSound(object)
end
end
)
end
--============================================================*
-- BACKPACK
--============================================================*
local Backpack =
Player:WaitForChild("Backpack")
scanContainer(
Backpack
)
--============================================================*
-- CHARACTER / EQUIPPED WEAPON
--============================================================*
local function setupCharacter(character)
scanContainer(
character
)
end
if Player.Character then
setupCharacter(
Player.Character
)
end
Player.CharacterAdded:Connect(
function(character)
setupCharacter(
character
)
end
)
--============================================================*
-- PLAYERGUI
--============================================================*
local PlayerGui =
Player:WaitForChild("PlayerGui")
scanContainer(
PlayerGui
)
--============================================================*
-- DONE
--============================================================*
only Prison Life tryhards remember this...
@ITzWo0zie did u remember to upload the full script
@benzo you download it and copy it idk but its preview