Vehicle Fading Sound Issues

It has been a while since the problem has been happening, so I may as well post it here.

Before I start, my friend Collect1ve made a post which got flagged due to the fact that he wasn’t able to explain it, so that’s where I come in. His post consisted of the following.

My friend (me, Avxnturador) made this script to add more detailed sounds to a car such as when the user lets off the throttle it’ll change the engine sound to a different sound, and also have multiple sounds instead of changing the pitch of 1. It worked perfectly a few days ago however now it is glitching and after being in a game for a few seconds it will just mute a select few of the sounds at random.

So, to sum it up, I have made a script that makes car engines sound better, I called it “Avxnturador’s Sound Suite”. It consisted of a local script, getting values such as the vehicle’s RPM, which then calculated the pitch and volume for each sound. It also consisted of a server script which connects to a RemoteEvent. Once called, it would retrieve the sounds, along with the pitch and volume for each sound, and it would update it.

The sounds would fade in and out, most of them overlapping each other, so volume and pitch were updated very frequently for each and every sound.

Most of the time, the sounds worked, however recently, the sounds have been known to “break”, which consisted of the sounds not updating anymore, even though they are receiving volume and pitch values, all while the sound is still playing.

What I have done so far is this.

  • Changed the table function so sounds automatically updated even if values were the same
  • Made it so sounds would stop if they had no volume, made it so they would play again when there was
  • Made it so sounds would never stopped, but once they would usually be inaudible, would change the volume to 1 and the pitch to 0
  • Transferred every pitch and volume calculation to the server script
  • Made it so when you pressed a key, every sound would duplicate, and the old sound would delete.
  • Same as above, except new sounds would be created, not duplicated. Every value would transfer.

Despite all of these attempts to fix the problem, some of the solutions made it so sounds would break less frequently, however eventually, sounds would break, usually with one breaking, then the rest breaking.

Other people and I have observed that the sounds would “break” when they have low volumes. This was the case as people said they could still hear the sounds when they broke, they were just very quiet. The sounds would also not break in Studio, so I could not get any values from there. I have tested the sounds in games, such as “Pacifico 2: Playground Town”, and in that game, the sounds break after a while. I had a function return to me the volume and pitch values from the sound themselves, and they were updating correctly, even when the sounds broke. (What I mean by that is, the sounds would have their pitch and volume values updated, however the sound would still be quiet and static, instead of being loud and with a rising pitch, per se.)

The weird thing is that the script used to work without any issues, however I cannot pinpoint around when the sounds started to break, as it was other people telling me that it wouldn’t work.

I apologize if any part of this topic is unclear. If any clarification is needed, ask and I will try my best to do it.

Examples of the local and server scripts used are below.

Here’s an example of the local script code, combining every other fix I have attempted. This local script, and the sounds it affects, has the breaking sound problem.

local car = script.Parent.Car.Value
local _Tune = require(car["A-Chassis Tune"])
local handler = car:WaitForChild("AC6_Sound")

car.Body:WaitForChild("Exh")

handler:FireServer("stopSound",car.Body.Exh.RevA)
handler:FireServer("stopSound",car.Body.Exh.RevB)
handler:FireServer("stopSound",car.Body.Exh.RevC)
handler:FireServer("stopSound",car.Body.Exh.RevD)
handler:FireServer("stopSound",car.Body.Exh.RevE)
handler:FireServer("stopSound",car.Body.Exh.RevIdle)
handler:FireServer("stopSound",car.Body.Exh.RevRed)
handler:FireServer("stopSound",car.Body.Exh.RelA)
handler:FireServer("stopSound",car.Body.Exh.RelB)
handler:FireServer("stopSound",car.Body.Exh.RelC)
handler:FireServer("stopSound",car.Body.Exh.RelD)
handler:FireServer("stopSound",car.Body.Exh.RelE)
handler:FireServer("stopSound",car.Body.Exh.RelIdle)
handler:FireServer("stopSound",car.Body.Exh.RelRed)
handler:FireServer("stopSound",car.Body.Exh.Elec)
wait()
handler:FireServer("playSound",car.Body.Exh.RevA)
handler:FireServer("playSound",car.Body.Exh.RevB)
handler:FireServer("playSound",car.Body.Exh.RevC)
handler:FireServer("playSound",car.Body.Exh.RevD)
handler:FireServer("playSound",car.Body.Exh.RevE)
handler:FireServer("playSound",car.Body.Exh.RevIdle)
handler:FireServer("playSound",car.Body.Exh.RevRed)
handler:FireServer("playSound",car.Body.Exh.RelA)
handler:FireServer("playSound",car.Body.Exh.RelB)
handler:FireServer("playSound",car.Body.Exh.RelC)
handler:FireServer("playSound",car.Body.Exh.RelD)
handler:FireServer("playSound",car.Body.Exh.RelE)
handler:FireServer("playSound",car.Body.Exh.RelIdle)
handler:FireServer("playSound",car.Body.Exh.RelRed)
handler:FireServer("playSound",car.Body.Exh.Elec)

local Drive={}
for i,v in pairs(car.Wheels:GetChildren()) do if v.Name=="RL" or v.Name=="RR" or v.Name=="R" then table.insert(Drive,v) end end
local wDia = 0
for i,v in pairs(Drive) do if v.Size.x>wDia then wDia = v.Size.x end end

handler:FireServer("values",_Tune,wDia)
local reset = false

game.Players.LocalPlayer:GetMouse().keyDown:connect(function(k) if k=="u" then reset = true end end)

game["Run Service"].Stepped:connect(function()
	handler:FireServer("updateSounds",script.Parent.Values.Throttle.Value,script.Parent.Values.RPM.Value,script.Parent.IsOn.Value,script.Parent.Values.Gear.Value,reset) reset = false
end)

Here is an example of the server script that hooks on to the RemoteEvent. This server script, and the sounds it affects, has the breaking sound problem.

local car = script.Parent.Parent
local F = {}

local on=0

local mlt = 1

local RevAPitch = 0.01
local RevARev = 3.05 * mlt

local RevBPitch = 0.01
local RevBRev = 2.3 * mlt

local RevCPitch = 0.01
local RevCRev = 1.85 * mlt

local RevDPitch = 0.01
local RevDRev = 1.525 * mlt

local RevEPitch = 0.01
local RevERev = 1.3 * mlt

local RelAPitch = 0.01
local RelARev = 4.1 * mlt

local RelBPitch = 0.01
local RelBRev = 1.85 * mlt

local RelCPitch = 0.01
local RelCRev = 1.85 * mlt

local RelDPitch = 0.01
local RelDRev = 1.525 * mlt

local RelEPitch = 0.01
local RelERev = 1.3 * mlt

local RevIdlePitch = .6*.75
local RevIdleRev = 2.75 * mlt

local RelIdlePitch = 1*.75
local RelIdleRev = 4.4 * mlt

local RevRedPitch = 0.01
local RevRedRev = 1.3 * mlt

local RelRedPitch = 0.01
local RelRedRev = 1.4 * mlt

local vol = 5 --Set the volume for everything below

local _Tune
local wDia
local resettime = tick()

local Sounds = {
	car.Body.Exh.RevA,
	car.Body.Exh.RevB,
	car.Body.Exh.RevC,
	car.Body.Exh.RevD,
	car.Body.Exh.RevE,
	car.Body.Exh.RelA,
	car.Body.Exh.RelB,
	car.Body.Exh.RelC,
	car.Body.Exh.RelD,
	car.Body.Exh.RelE,
	car.Body.Exh.RevIdle,
	car.Body.Exh.RelIdle,
	car.Body.Exh.RevRed,
	car.Body.Exh.RelRed,
	car.Body.Exh.Elec
}

F.updateSounds = function(throt,_RPM,isOn,gear,reset)
	if not isOn then on=math.max(on-1,0) else on=1 end
	
	local function pitch(pit,rev) return math.max((((pit + rev*_RPM/_Tune.Redline))*on^2),pit) end
	local volBase = throt*(0.5+(0.5*(math.sqrt(_RPM/_Tune.Redline))))
	local relBase = (1-throt)*(0.5+(0.5*(math.sqrt(_RPM/_Tune.Redline))))
	
	local RevAP = pitch(RevAPitch,RevARev) * on
	local RevBP = pitch(RevBPitch,RevBRev) * on
	local RevCP = pitch(RevCPitch,RevCRev) * on
	local RevDP = pitch(RevDPitch,RevDRev) * on
	local RevEP = pitch(RevEPitch,RevERev) * on
	
	local RelAP = pitch(RelAPitch,RelARev) * on
	local RelBP = pitch(RelBPitch,RelBRev) * on
	local RelCP = pitch(RelCPitch,RelCRev) * on
	local RelDP = pitch(RelDPitch,RelDRev) * on
	local RelEP = pitch(RelEPitch,RelERev) * on
	
	local RevIP = pitch(RevIdlePitch,RevIdleRev) * on
	local RelIP = pitch(RelIdlePitch,RelIdleRev) * on
	
	local RevRP = pitch(RevRedPitch,RevRedRev) * on
	local RelRP = pitch(RelRedPitch,RelRedRev) * on
	
	local IdleV = (1 - math.max(math.min(((_RPM/_Tune.Redline)*16)-1,1),0.001))
	local RedV = math.max(math.min(((_RPM/_Tune.Redline)*100)-98,1),0.001)
	
	local RevIV = math.max(volBase*IdleV,0.001)
	local RelIV = math.max(relBase*IdleV,0.001)
	
	local RevRV = math.max(volBase*RedV,0.001)
	local RelRV = math.max(relBase*RedV,0.001)
	
	local RevAV = math.max(volBase * (1-math.max(math.min(((_RPM/_Tune.Redline)*5)-1,1),0)) - IdleV * on,0.001) 
	local RevBV = math.max(volBase * math.max(math.min(((_RPM/_Tune.Redline)*5)-1,1),0) - math.max(math.min(((_RPM/_Tune.Redline)*5)-2,1),0) * on,0.001)
	local RevCV = math.max(volBase * math.max(math.min(((_RPM/_Tune.Redline)*5)-2,1),0) - math.max(math.min(((_RPM/_Tune.Redline)*5)-3,1),0) * on,0.001)
	local RevDV = math.max(volBase * math.max(math.min(((_RPM/_Tune.Redline)*5)-3,1),0) - math.max(math.min(((_RPM/_Tune.Redline)*5)-4,1),0) * on,0.001)
	local RevEV = math.max(volBase * math.max(math.min(((_RPM/_Tune.Redline)*5)-4,1),0) - RedV * on,0.001)
	
	local RelAV = math.max(relBase * (1-math.max(math.min(((_RPM/_Tune.Redline)*5)-1,1),0)) - IdleV * on,0.001) 
	local RelBV = math.max(relBase * math.max(math.min(((_RPM/_Tune.Redline)*5)-1,1),0) - math.max(math.min(((_RPM/_Tune.Redline)*5)-2,1),0) * on,0.001)
	local RelCV = math.max(relBase * math.max(math.min(((_RPM/_Tune.Redline)*5)-2,1),0) - math.max(math.min(((_RPM/_Tune.Redline)*5)-3,1),0) * on,0.001)
	local RelDV = math.max(relBase * math.max(math.min(((_RPM/_Tune.Redline)*5)-3,1),0) - math.max(math.min(((_RPM/_Tune.Redline)*5)-4,1),0) * on,0.001)
	local RelEV = math.max(relBase * math.max(math.min(((_RPM/_Tune.Redline)*5)-4,1),0) - RedV * on,0.001)
	
	
	if RevAV<0.002 then
		RevAV=.1
		RevAP=0
	end
	if RevBV<0.002 then
		RevBV=.1
		RevBP=0
	end
	if RevCV<0.002 then
		RevCV=.1
		RevCP=0
	end
	if RevDV<0.002 then
		RevDV=.1
		RevDP=0
	end
	if RevEV<0.002 then
		RevEV=.1
		RevEP=0
	end
	if RelAV<0.002 then
		RelAV=.1
		RelAP=0
	end
	if RelBV<0.002 then
		RelBV=.1
		RelBP=0
	end
	if RelCV<0.002 then
		RelCV=.1
		RelCP=0
	end
	if RelDV<0.002 then
		RelDV=.1
		RelDP=0
	end
	if RelEV<0.002 then
		RelEV=.1
		RelEP=0
	end
	if IdleV<0.002 then
		RevIV=.1
		RelIV=.1
		RevIP=0
		RelIP=0
	end
	if RedV<0.002 then
		RevRV=.1
		RelRV=.1
		RevRP=0
		RelRP=0
	end
	
	local GRPitch = 0
	
	if gear ~= 0 then GRPitch = _RPM/_Tune.Redline end
	
	car.Body.Exh.RevA.Pitch = RevAP
	car.Body.Exh.RevA.Volume = RevAV*vol
	
	car.Body.Exh.RevB.Pitch = RevBP
	car.Body.Exh.RevB.Volume = RevBV*vol
	
	car.Body.Exh.RevC.Pitch = RevCP
	car.Body.Exh.RevC.Volume = RevCV*vol
	
	car.Body.Exh.RevD.Pitch = RevDP
	car.Body.Exh.RevD.Volume = RevDV*vol
	
	car.Body.Exh.RevE.Pitch = RevEP
	car.Body.Exh.RevE.Volume = RevEV*vol
	
	car.Body.Exh.RelA.Pitch = RelAP
	car.Body.Exh.RelA.Volume = RelAV*vol
	
	car.Body.Exh.RelB.Pitch = RelBP
	car.Body.Exh.RelB.Volume = RelBV*vol
	
	car.Body.Exh.RelC.Pitch = RelCP
	car.Body.Exh.RelC.Volume = RelCV*vol
	
	car.Body.Exh.RelD.Pitch = RelDP
	car.Body.Exh.RelD.Volume = RelDV*vol
	
	car.Body.Exh.RelE.Pitch = RelEP
	car.Body.Exh.RelE.Volume = RelEV*vol
	
	car.Body.Exh.RevIdle.Pitch = RevIP
	car.Body.Exh.RevIdle.Volume = RevIV*vol
	
	car.Body.Exh.RelIdle.Pitch = RelIP
	car.Body.Exh.RelIdle.Volume = RelIV*vol
	
	car.Body.Exh.RevRed.Pitch = RevRP
	car.Body.Exh.RevRed.Volume = RevRV*vol
	
	car.Body.Exh.RelRed.Pitch = RelRP
	car.Body.Exh.RelRed.Volume = RelRV*vol
	
	car.Body.Exh.Elec.Pitch = GRPitch*1.5
	car.Body.Exh.Elec.Volume = car.Body.Exh.Elec.Volume/2
	
	if reset and tick()-resettime>1 then
		resettime=tick()
		for _,i in pairs(Sounds) do
			local new = i:Clone()
			new.Parent = i.Parent
			i:Destroy()
		end
	end
end

F.values = function(tn,wdia)
	_Tune = tn
	wDia = wdia
end

F.playSound = function(snd) snd:Play() end

F.stopSound = function(snd) snd:Stop() end

script.Parent.OnServerEvent:connect(function(pl,Fnc,...) F[Fnc](...) end)

car.DriveSeat.ChildRemoved:connect(function(child)
	if child.Name=="SeatWeld" then
		pcall(function() 
			F.stopSound(car.Body.Exh.RevA)
			F.stopSound(car.Body.Exh.RevB)
			F.stopSound(car.Body.Exh.RevC)
			F.stopSound(car.Body.Exh.RevD)
			F.stopSound(car.Body.Exh.RevE)
			F.stopSound(car.Body.Exh.RelA)
			F.stopSound(car.Body.Exh.RelB)
			F.stopSound(car.Body.Exh.RelC)
			F.stopSound(car.Body.Exh.RelD)
			F.stopSound(car.Body.Exh.RelE)
			F.stopSound(car.Body.Exh.RevIdle)
			F.stopSound(car.Body.Exh.RelIdle)
			F.stopSound(car.Body.Exh.RevRed)
			F.stopSound(car.Body.Exh.RelRed)
			F.stopSound(car.Body.Exh.Elec)
		end)
	end
end)

TL;DR: Sounds are being updated frequently, and they fade in and out of each other, changing volume and pitch, but after a while, the sounds no longer update, making everyone go :rage::rage::rage:

3 Likes
I coded your script in my style so it was significantly easier on the eyes and less local variables. I obviously couldn't test this.

Local:

local Players = game:GetService("Players")
local RunService = game:GetService("RunService")

local car = script.Parent.Car.Value
local _Tune = require(car["A-Chassis Tune"])
local handler = car:WaitForChild("AC6_Sound")

local sounds = {
	"RevA",
	"RevB",
	"RevC",
	"RevD",
	"RevE",
	"RevIdle",
	"RevRed",
	"RelA",
	"RelB",
	"RelC",
	"RelD",
	"RelE",
	"RelIdel",
	"RelRed",
	"Elec"
}

local Exh = car.Body:WaitForChild("Exh")


for _,name in pairs(sounds) do
	handler:FireServer("stopSound", Exh[name])
end
wait()
for _,name in pairs(sounds) do
	handler:FireServer("playSound", Exh[name])
end

local wDia
for _,wheel in pairs(car.Wheels:GetChildren()) do
	if wheel.Name == "RL" or wheel.Name == "RR" or wheel.Name == "R" and
		wheel.Size.X > wDia
	then
		wDia = wheel.Size.X
	end
end

handler:FireServer("values",_Tune,wDia)
local reset = false

Players.LocalPlayer:GetMouse().keyDown:Connect(function(k)
	if k == "u" then
		reset = true
	end
end)

RunService.Stepped:Connect(function()
	handler:FireServer(
		"updateSounds",
		script.Parent.Values.Throttle.Value,
		script.Parent.Values.RPM.Value,
		script.Parent.IsOn.Value,
		script.Parent.Values.Gear.Value,
		reset
	)
	reset = false
end)

Server:

local car = script.Parent.Parent
local F = {}

local on = 0

local mlt = 1

local Exh = car.Body.Exh

local sounds = {
	RevA = {
		Source = Exh.RevA,
		Pitch = 0.01,
		Rev = 3.05 * mlt
	},
	RevB = {
		Source = Exh.RevB,
		Pitch = 0.01,
		Rev = 2.3 * mlt
	},
	RevC = {
		Source = Exh.RevC,
		Pitch = 0.01,
		Rev = 1.85 * mlt
	},
	RevD = {
		Source = Exh.RevD,
		Pitch = 0.01,
		Rev = 1.525 * mlt
	},
	RevE = {
		Source = Exh.RevE,
		Pitch = 0.01, 
		Rev = 1.3 * mlt
	},
	RevIdle = {
		Source = Exh.RevIdle,
		Pitch = 0.01, 
		Rev = 2.75 * mlt
	},
	RevRed = {
		Source = Exh.RevRed,
		Pitch = 0.01, 
		Rev = 1.3 * mlt
	},
	RelA = {
		Source = Exh.RelA,
		Pitch = 0.01, 
		Rev = 4.1 * mlt
	},
	RelB = {
		Source = Exh.RelB,
		Pitch = 0.01, 
		Rev = 1.85 * mlt
	},
	RelC = {
		Source = Exh.RelC,
		Pitch = 0.01, 
		Rev = 1.85 * mlt
	},
	RelD = {
		Source = Exh.RelD,
		Pitch = 0.01, 
		Rev = 1.525 * mlt
	},
	RelE = {
		Source = Exh.RelE,
		Pitch = 0.01, 
		Rev = 1.3 * mlt
	},
	RelIdle = {
		Source = Exh.RelIdle,
		Pitch = 1*.75, 
		Rev = 4.4 * mlt
	},
	RelRed = {
		Source = Exh.RelRed,
		Pitch = 0.01, 
		Rev = 1.4 * mlt
	}
}

local vol = 5 --Set the volume for everything below

local _Tune
local wDia
local resettime = tick()

F.updateSounds = function(throt,_RPM,isOn,gear,reset)
	local volRatio = _RPM/_Tune.Redline
	if not isOn then
		on = math.max(on - 1, 0)
	else
		on = 1
	end
	
	local function pitch(pit,rev)
		return math.max( (rev*_RPM/_Tune.Redline + pit) * on^2,pit)
	end
	local volBase = throt * (0.5 * math.sqrt(_RPM/_Tune.Redline) + 0.5)
	local relBase = (1-throt)*(0.5*math.sqrt(_RPM/_Tune.Redline) + 0.5)

	local P = {}
	for name,properties in pairs(sounds) do
		P[name] = pitch(properties.Pitch,properties.Rev) * on
	end
	
	local IdleV = 1 - math.clamp(16 * _RPM/_Tune.Redline - 1,0.001,1)
	local RedV = math.clamp(100 * _RPM/_Tune.Redline - 98,0.001,1)

	local function returnVol(base, term1, term2)
		return math.max(base * term1 - term2 * on, 0.001)
	end

	local function returnVolA(base, term)
		return math.max(base * (1 - math.clamp(5 * _RPM/_Tune.Redline - 1, 0, 1)) - term * on, 0.001)

	local function returnVolBCD(base,offset1, offset2)
		return math.max(base * math.clamp(5 * _RPM/_Tune.Redline - offset1, 0, 1) - math.clamp(5 * _RPM/_Tune.Redline - offset2, 0, 1) * on, 0.001)
	end

	local function returnVolE(base, term)
		return math.max(base * math.clamp(5 * _RPM/_Tune.Redline - 4, 0, 1) - term * on, 0, 1), 0.001)
	end
	
	local V = {
		RevA = returnVolA(volBase, IdleV),
		--math.max(volBase * (1 - math.clamp(5 * _RPM/_Tune.Redline - 1, 0, 1)) - IdleV * on, 0.001),

		RevB = returnVolBCD(volBase, 1, 2),
		--math.max(volBase * math.clamp(5 * _RPM/_Tune.Redline - 1, 0, 1) - math.clamp(5 * _RPM/_Tune.Redline - 2, 0, 1) * on, 0.001),

		RevC = returnVolBCD(volBase, 2, 3),
		--math.max(volBase * math.clamp(5 * _RPM/_Tune.Redline - 2, 0, 1) - math.clamp(5 * _RPM/_Tune.Redline - 3, 0, 1) * on, 0.001),

		RevD = returnVolBCD(volBase, 3, 4),
		--math.max(volBase * math.clamp(5 * _RPM/_Tune.Redline - 3, 0, 1) - math.clamp(5 * _RPM/_Tune.Redline - 4, 0, 1) * on, 0.001),

		RevE = returnVolE(volBase, RedV),
		--math.max(volBase * math.clamp(5 * _RPM/_Tune.Redline - 4, 0, 1) - RedV * on, 0.001),

		RelA = returnVolA(relBase, IdleV),	
		RelB = returnVolBCD(relBase, 1, 2),
		RelC = returnVolBCD(relBase, 2, 3),
		RelD = returnVolBCD(relBase, 3, 4),
		RelE = returnVolE(relBase, RedV),
		
		RevIdle = math.max(volBase * IdleV, 0.001),
		RelIdle = math.max(relBase * IdleV, 0.001),
		RevRed = math.max(volBase * RedV, 0.001),
		RelRed = math.max(relBase * RedV, 0.001)
	}

	for name,volume in pairs(V) do
		if volume < 0.002 then
			V[name] = 0.1
			P[name] = 0
		end
	end

	local GRPitch = 0
	
	if gear ~= 0 then
		GRPitch = _RPM/_Tune.Redline
	end
	
	for name,sound in pairs(sound) do
		sound.Source.Pitch = P[name]
		sound.Source.Volume = V[name]
	end

	Exh.Elec.Pitch = GRPitch * 1.5
	Exh.Elec.Volume = Exh.Elec.Volume/2

	if reset and tick() - resettime > 1 then
		resettime = tick()
		for _,sound in pairs(sounds) do
			local i = sound.Source
			local new = i:Clone()
			new.Parent = i.Parent
			i:Destroy()
			sound.Source = new
		end
	end
end

F.values = function(tn,wdia)
	_Tune = tn
	wDia = wdia
end

F.playSound = function(snd) snd:Play() end
F.stopSound = function(snd) snd:Stop() end

script.Parent.OnServerEvent:Connect(function(pl,Fnc,...)
	F[Fnc](...)
end)

car.DriveSeat.ChildRemoved:Connect(function(child)
	if child.Name == "SeatWeld" then
		pcall(function()
			for _,sound in pairs(sounds) do
				F.stopSound(sound.Source)
			end
			F.stopSound(Exh.Elec)
		end)
	end
end)

I think I know the problem here: remote events have a throttle on how many times you can fire them, I think it is ten per second?
From Remote Functions and Events on the dev wiki:


Your script could be fixed by changing RunService.RenderStepped in your local script to a while do loop, with a wait of 0.1 seconds or larger in the body.

A different, much better approach would be making the entire sound script either client-sided or server-sided to get rid of remote events altogether. I would make it client-sided because you are using sound, which is technically displaying the car.

It might be something else though? It could be due to the equations you use to create your pitch and volume, though I am quite sure you have quadruple checked that.

7 Likes

To add on to what @goldenstein64 said.

I would totally take the client side approach, and simply calculate engine rpm from wheel rpm, which should be automagically replicated from the server, saving you the need to do a remote event.

Then you can simply play the sound locally on the client for said engine speed. Though this might not work too well depending on ping. Haha and if someone lagged hard, I’d assume the engine would stay at the same rpm for quite some time. But hey experiment and you might find something usable. :slight_smile:

2 Likes

Sorry for straying slightly off-topic but could you help me out in my efforts to calculate engine RPM from wheel RPM? My issue is discussed in more detail in the following topic, and multiple attempts to fix it are in the replies:

I’m afraid I was only able to come up with this solution after getting EngineRPM from WheelRPM, and that was a couple years ago when I was using Unity. Closer to 2011.

On top of being bad at math, I wouldn’t know how to do it. :frowning: Sorry. I’m sure someone else will be able to provide more information. :slight_smile:

1 Like

If your car needs to be 4WD (all wheels are the same speed), you will have to link them via constraints. Then all you need to do is average all the wheel RPMs and multiply by the gear ratio (it goes down the higher your gear is). If AWD, link the front wheels together and the back wheels together and calculate the average. RWD, do just the rear wheels. Something like that. Either that or take the maximum wheel RPM. Honestly it depends, I haven’t done it myself but it could be done. Also, below a certain RPM you can have the engine simulate its own RPM for something like an automatic engine that can run without turning the wheels.

Here’s what I’d do to calculate some wheel RPM (not accounting for gear ratio, and only for 4-wheeled vehicles):

  • 4WD: Link all wheels (including front to back) via constraints so they rotate at the same speed. Take the average of this rather than the speed of any one wheel to account for physics inaccuracies.
  • AWD: Link the two front wheels together, and link the back two wheels together (for a fixed differential). Since AWD vehicles (that are not 4WD) don’t have a fixed differential between the front and back wheels, it’s your responsibility to calculate the RPM based on this. But to calculate the RPM for each pair of wheels, simply take the average of the two wheels since they’re fixed together. Then you have two RPMs, do what you want to with that.
  • RWD & FWD: AWD but only one pair of wheels. Link them via constraints and calculate average RPM

Finally, I’ve returned.

Before I continue on, I would like to point out that the chassis’ that are being used are the A-Chassis suite of chassis’, specifically A-Chassis 6.81T (and older variants), and A-Chassis 6C Version 1.2, Updates 1-4 (and older versions). This comes into play, especially with AC6C.

@goldenstein64 I’ve tried your scripts, and while it’s infinitely better and more efficient, the sounds still break when they reach low-enough volumes, which doesn’t solve the bigger problem (the sounds breaking). Furthermore, the events fired are not the problem, as the sounds don’t lag, it’s just the sounds themselves breaking.

@T0ny The engine RPM is a completely different calculation that’s handled by A-Chassis, so I’d be unable to calculate engine RPM from wheel RPM. Aside that, I’ve not tried local sounds, but I’d be willing to give it a try. Knowing the problem at hand, I don’t think it’d be a fix though, sadly.

And to the rest of the people wondering about calculating RPM, Terrodactyl has you covered cause that’s how it’s calculated.

I should also point out that another friend (IMeanBiz) who’s made their own script that does the same thing as mine (fading sounds) has had trouble with his scripts too. If I recall correctly, since I think I’ve heard it once, I think a friend of IMeanBiz said that his script was broken (saying the sounds broke), and I knew that it was the same problem that I’m having. I also recall seeing his script, and it’s definitely simpler than mine, despite the whitespace being all over the place.

I also say again, the only “fix” for this is to clone the sounds affected, but doing that repeatedly is very tiring, and it doesn’t solve the main issue.

I’ve also noticed that it mainly happens when you’re in game with a few other players. I’ve mentioned “Pacifico 2: Playground Town”, in which that’s one place where it happens, alongside other places that would sometimes give lag spikes, whether it be physics, render, or networking related.

1 Like

I’m honestly surprised, that was just a guess!