Making subtitles from baldi's basics

so i wanna make the subtitles system that will act like captions from the games baldi’s basics classic remastered / baldi’s basics plus, basically they should be positioned on screen based on the sound’s location relatively to the camera and move around the center in a circle or something like that, like if the sound is to the left then the subtitle is at the left, if the sound is in front of the player then the subtitle should be at the top and so on, sorry if my explanation wasn’t good but i hope you understood me, i tried implementing it with chatgpt but the subtitles that were made didn’t really work well
the script that i have right now:

local cam = workspace.CurrentCamera
local player = game.Players.LocalPlayer
local stringArr = {
  -- phrases here
}

local subtitles = {}

local function createSub(sound, text, color)
	local subtitle = script.Subtitle:Clone()
	subtitle.Txt.Text = text
	subtitle.Txt.TextColor3 = color
	subtitle.Parent = script.Parent.Frame
	subtitle.SubID.Value = sound.Name
	return subtitle
end

local function deleteSub(id)
	for i, v in pairs(subtitles) do
		if v.SubID.Value == id then
			v:Destroy()
			table.remove(subtitles, i)
		end
	end
end

local function updateSubPosition(subtitle, sound)
	if sound.Parent and sound.Parent:IsA("Part") then
		-- i wanna do the subs position here
	end
end

local function onSoundPlaying(sound)
	local subText
	local subColor

	if string.find(sound.Name, "BAL") then
		subColor = Color3.new(0, 1, 0)
	elseif string.find(sound.Parent.Parent.Name, "Playtime") then
		subColor = Color3.new(1, 0, 0)
	else
		subColor = Color3.new(1, 1, 1)
	end

	if stringArr[sound.Name] then
		subText = stringArr[sound.Name]
	end
	local subtitle = createSub(sound, subText, subColor)
	table.insert(subtitles, subtitle)

	local connection
	connection = sound.Stopped:Connect(function()
		deleteSub(sound.Name)
		connection:Disconnect()
	end)

	game:GetService("RunService").RenderStepped:Connect(function()
		updateSubPosition(subtitle, sound)
	end)
end

for _, sound in pairs(game:GetDescendants()) do
	if sound:IsA("Sound") then
		sound.Played:Connect(function()
			if not stringArr[sound.Name] then
				return
			else
				onSoundPlaying(sound)
			end
		end)
		sound.Ended:Connect(function() deleteSub(sound.Name) end)
	end
end

game.DescendantAdded:Connect(function(sound)
	if sound:IsA("Sound") then
		sound.Played:Connect(function()
			if not stringArr[sound.Name] then
				return
			else
				onSoundPlaying(sound)
			end
		end)
		sound.Ended:Connect(function() deleteSub(sound.Name) end)
	end
end)

I think the part you’re missing is the calculation of the position of the subtitle based on the sound’s position relative to the camera