Basic TTS - What is Going Wrong?

My goal is to get the audio from the TTS instance to play while SoundService.DefaultListenerLocation is equal to Enum.ListenerLocation.Default. I cannot change it at runtime (due to needing PluginSecurity), nor do I want to push a new update to my place just for basic TTS.
The problem is, I cannot get the thing to play locally from the player instead of globally. (Like a Sound parented to a character’s head v. Workspace.)
I tried to look around the Creator Hub, yet came up empty handed. I have no idea why the output is not working.

local voice = "10"
local message = "Hello, World!"
local speaker = game:GetService('Players'):GetPlayers()[1] -- or similar
--vvvvv runs client code as a compiled LocalScript (works the same as a normal LocalScript)
runCode('SpawnL',[[
	local plrs = game:GetService("Players")
	local localPlayer = plrs.LocalPlayer

	local target = plrs:FindFirstChild("]]..speaker.Name..[[")
	if not target then return end

	local char = target.Character
	if not char then return end

	local root = char:FindFirstChild("HumanoidRootPart")
	if not root then return end

	local camera = workspace.CurrentCamera
	if not camera then return end

	local emitter = root:FindFirstChild("TTSEmitter")
	if not emitter then
		emitter = Instance.new("AudioEmitter")
		emitter.Name = "TTSEmitter"
		emitter.Parent = root
	end

	local output = camera:FindFirstChild("TTSOutput")
	if not output then
		output = Instance.new("AudioDeviceOutput")
		output.Name = "TTSOutput"
		output.Parent = camera
	end
	output.Player = localPlayer

	local tts = Instance.new("AudioTextToSpeech")
	tts.Parent = root
	tts.VoiceId = "]]..voice..[["
	tts.Text = "]]..message..[["
	tts.Volume = 3

	local wire1 = Instance.new("Wire")
	wire1.SourceInstance = tts
	wire1.TargetInstance = emitter
	wire1.Parent = root

	local wire2 = Instance.new("Wire")
	wire2.SourceInstance = emitter
	wire2.TargetInstance = output
	wire2.Parent = root

	local status = tts:LoadAsync()
	if status == Enum.AssetFetchStatus.Success then
		warn('play') -- prints
		tts:Play()
		tts.Ended:Wait()
		warn('ended') -- prints
	end

	wire2:Destroy()
	wire1:Destroy()
	tts:Destroy()
]],player.PlayerGui) -- this is ran in everybody's playergui all at once

Am I missing something? What’s going wrong?

1 Like

The issue is likely your wire setup. You are wiring the emitter to an AudioDeviceOutput parented to the camera, but if the listener is still at the default location, it won’t hear anything from the root part regardless of where you point the output.

Hi! Thanks for the reply.
Do you know where the listener should go? Where should the output go?