local g=.35 local R=0 local Z=0 local j=false local O=0 local w=1 local h=1.5 local U=.85 local i=1 local k=script.Parent.Engine k:Play()local function Y(g)return.014/(.2*g+.08)end while true do wait()Z=(R/#Wheels+Z)/2 R=0 for p,P in pairs(Wheels)do local n=P.Wheel local A=(-Base.CFrame.UpVector*n.Size.Y)/1.925 local m,S,u=Raycast.new(n.Position,A,script.Parent.Parent)if m then local p=-(P.Wheel.CFrame:vectorToObjectSpace(n.RotVelocity)).X R=R+math.abs(p)local A=n.Velocity+((p*n.Size.Y)/2)*n.CFrame.rightVector:Cross(u)local m=n.CFrame:vectorToObjectSpace(A)local N=A.magnitude P.AttCenter.Position=AttachmentPart.CFrame:PointToObjectSpace(S)local f=AttachmentPart.CFrame:VectorToObjectSpace((u:Cross(n.Velocity)).unit)local a=(f*.044)*math.clamp(N-27,0,80)^.5+u*.175 P.AttL.Position=P.AttCenter.Position+a P.AttR.Position=P.AttCenter.Position-a P.Smoke.Rate=math.max(0,N-27)^.5 P.DriftSound.Pitch=(math.clamp(4.1/N^.28,.9,2.2)+P.DriftSound.Pitch*3)/4 P.DriftSound.Volume=(math.clamp(.009*N^1.2,0,2.5)+P.DriftSound.Volume*3)/4 k.Volume=.1+.4*math.max(Throttle.Value,0)local E=Z*Y(w)if not j then if E>h then i=w w=w+1 j=true O=elapsedTime()elseif E<U and w>1 then i=w w=w-1 j=true O=elapsedTime()end else local R=(elapsedTime()-O)/g E=Z*(R*Y(w)+(1-R)*Y(i))if R>=1 then j=false end end k.Pitch=math.max(E,.3)if N>21 then P.Beam.Enabled=true P.Smoke.Enabled=true if not P.DriftSound.Playing then P.DriftSound:Play()end else P.Beam.Enabled=false P.Smoke.Enabled=false if P.DriftSound.Playing then P.DriftSound:Stop()end end else P.Beam.Enabled=false P.Smoke.Enabled=false if P.DriftSound.Playing then P.DriftSound:Stop()end end end end
--Engine Sound stuff
local ShiftLength = 0.35
local OmegaSum = 0
local AvgOmega = 0
local Shifting = false
local ShiftStart = 0
local Gear = 1
local ShiftUp = 1.5
local ShiftDown = 0.85
local OldGear = 1
local EngineSound = script.Parent.Engine
EngineSound:Play()
local function GearRatio(Num)
	return 0.014 / (0.2 * Num + 0.08)
end

while true do
	wait()
	AvgOmega = (OmegaSum / #Wheels + AvgOmega) / 2
	OmegaSum = 0
	for i, v in pairs(Wheels) do
		local Wheel = v.Wheel
		--Raycast to find if the wheel is touching the ground
		local OffsetVector = -Base.CFrame.UpVector * Wheel.Size.Y / 1.925
		local Hit, Pos, Normal = Raycast.new(Wheel.Position, OffsetVector, script.Parent.Parent)
		--Touching
		if Hit then
			--Calculate velocity of bottom of wheel
			local Omega = -v.Wheel.CFrame:vectorToObjectSpace(Wheel.RotVelocity).X
			OmegaSum = OmegaSum + math.abs(Omega)
			local ContactVelocity = Wheel.Velocity + Omega * Wheel.Size.Y / 2 * Wheel.CFrame.rightVector:Cross(Normal)
			local ObjSpaceVel = Wheel.CFrame:vectorToObjectSpace(ContactVelocity)
			local SlideSpeed = ContactVelocity.magnitude

			--Position Attachments
			v.AttCenter.Position = AttachmentPart.CFrame:PointToObjectSpace(Pos)
			local PerpVector = AttachmentPart.CFrame:VectorToObjectSpace(Normal:Cross(Wheel.Velocity).unit)
			local Offset = PerpVector * 0.044 * (math.clamp(SlideSpeed - 27, 0, 80)) ^ 0.5 + Normal * 0.175
			v.AttL.Position = v.AttCenter.Position + Offset
			v.AttR.Position = v.AttCenter.Position - Offset
			v.Smoke.Rate = (math.max(0, SlideSpeed - 27)) ^ 0.5

			--Tyre Sound
			v.DriftSound.Pitch = (math.clamp(4.1 / (SlideSpeed ^ 0.28), 0.9, 2.2) + v.DriftSound.Pitch * 3) / 4
			v.DriftSound.Volume = (math.clamp(0.009 * SlideSpeed ^ 1.2, 0, 2.5) + v.DriftSound.Volume * 3) / 4

			--Engine Sounds
			EngineSound.Volume = 0.1 + 0.4 * math.max(Throttle.Value, 0)
			local RawPitch = AvgOmega * GearRatio(Gear)
			if not Shifting then
				if RawPitch > ShiftUp then
					OldGear = Gear
					Gear = Gear + 1
					Shifting = true
					ShiftStart = elapsedTime()
				elseif RawPitch < ShiftDown and Gear > 1 then
					OldGear = Gear
					Gear = Gear - 1
					Shifting = true
					ShiftStart = elapsedTime()
				end
			else
				local pct = (elapsedTime() - ShiftStart) / ShiftLength
				RawPitch = AvgOmega * (pct * GearRatio(Gear) + (1 - pct) * GearRatio(OldGear))
				if pct >= 1 then
					Shifting = false
				end
			end
			EngineSound.Pitch = math.max(RawPitch, 0.3)

			--Enable or disable tyre sounds and trails
			if SlideSpeed > 21 then
				v.Beam.Enabled = true
				v.Smoke.Enabled = true
				if not v.DriftSound.Playing then
					v.DriftSound:Play()
				end
			else
				v.Beam.Enabled = false
				v.Smoke.Enabled = false
				if v.DriftSound.Playing then
					v.DriftSound:Stop()
				end
			end
		else --Airborn
			v.Beam.Enabled = false
			v.Smoke.Enabled = false
			if v.DriftSound.Playing then
				v.DriftSound:Stop()
			end
		end
	end
end
