Onex
Onex
Home
Products
Documentation
Changelog
Login with FiveM
  • 👋 Welcome
  • Claim Purchase
  • Translations
    • Weaponmeta
    • Voice Interaction
      Integrations
      Installation
      Configuration
      Features
      Api
      Action
      Events
      Layers
      Npc
Artifacts Tracker
  1. Onex Scripts
  2. Scripts_guides / Speech & Tts
Ctrl K

SPEECH & TTS#

The speech API provides text-to-speech output via the browser TTS engine. Supports both global (2D) audio and 3D positional audio attached to ped entities or world coordinates.

Networked audio: When a 3D speak call is made for a networked entity (and network audio is enabled for the calling addon), the sound is broadcast to nearby players automatically via the server relay. Other players hear the speech spatially from the entity's position.

speak#

Synthesize and play TTS audio. Pass an entity or coords to produce 3D positioned audio; omit both for global audio.

Syntax
exports['onex-voiceInteraction']:speak(text, options)
NameTypeDescription
textstringText to speak. Required, non-empty.
options.voicestring | tableVoice name string ("en-US-GuyNeural") or voice object — see below.
options.entitynumberPed entity handle for 3D positioned audio. Voice is auto-detected from NPC config if not specified.
options.coordsvector3World coordinates for 3D audio without a ped entity.
options.maxDistancenumberHearing range in metres for 3D audio (default 30.0).
options.animationtable | falseAnimation options for ped entities. false disables all animation.
options.showSubtitlebooleanDisplay a subtitle synced to actual TTS duration.
options.immediateSubtitlebooleanDisplay subtitle immediately without waiting for TTS timing.
options.npcNamestringSpeaker name shown in the subtitle.
options.networkedbooleanBroadcast 3D audio to nearby players via server relay.

Returns: { success = true, data = { soundId = "sound_12345_6789", is3D = true } }

For global audio, soundId is nil and is3D is false. For 3D audio, soundId is a string you can pass to stopSpeech.

Voice object format#

The voice field accepts either a plain string name or a full settings object:

-- String(name only) voice = "en-US-GuyNeural" -- Object(full settings) voice = { name = "en-US-GuyNeural", -- voice identifier rate = 1.0, -- speech rate(default 1.0) pitch = 1.0, -- pitch modifier(default 1.0) volume = 0.8, -- volume 0.0–1.0 (default 1.0) stability = 0.5, -- ElevenLabs stability(0.0–1.0, optional) similarityBoost = 0.75 -- ElevenLabs similarity boost(0.0–1.0, optional) }

The legacy flat structure (options.rate, options.pitch, options.volume at the top level) is also supported for backward compatibility.

Animation options#

For entity-based 3D audio on peds, lip-sync and gesture animations are enabled by default:

animation = { lipSync = true, -- default: true gesture = true, -- default: true returnToIdle = true, -- return to idle after gesture(default: true) gestureDict = nil, -- custom gesture animation dict gestureAnim = nil, -- custom gesture animation name idleScenario = nil -- idle scenario to play after speech }

Pass animation = false to disable all animation entirely.

Your Script
-- Simple global TTS exports['onex-voiceInteraction']:speak("Hello, this is a global announcement.", { voice = "en-US-GuyNeural" }) -- With full voice settings exports['onex-voiceInteraction']:speak("Attention all units.", { voice = { name = "en-US-EricNeural", rate = 0.95, pitch = 1.0, volume = 0.9 } })

stopSpeech#

Stop TTS playback. Stop a specific 3D sound by ID or stop all active sounds at once.

Syntax
exports['onex-voiceInteraction']:stopSpeech(soundId)
NameTypeDescription
soundIdstringSpecific 3D sound ID returned from speak. Omit to stop all sounds.

Returns: { success = true, data = { stopped = 1 } } — stopped is -1 when stopping all (count unknown).

Your Script
-- Stop all TTS(global + all 3D) exports['onex-voiceInteraction']:stopSpeech() -- Stop a specific 3D sound exports['onex-voiceInteraction']:stopSpeech("sound_12345_6789")

getVoices#

Retrieve the list of available TTS voices from the browser engine. Async — the browser engine must be ready.

Syntax
exports['onex-voiceInteraction']:getVoices(callback, timeout)
NameTypeDescription
callbackfunctionfunction(result) — called with { success, data = { voices } } on completion or { success = false, code = "TIMEOUT" } on timeout.
timeoutnumberMilliseconds before callback fires with a timeout error (default 5000).

Without a callback: returns immediately with { success = true, data = { pending = true, listenEvent = "onex-voiceInteraction:tts:voices" } }. Listen to the named event to receive the voice list asynchronously.

Your Script
exports['onex-voiceInteraction']:getVoices(function(result) if not result.success then print("Failed to get voices:", result.code) return end for _, voice in ipairs(result.data.voices) do print(voice.name, voice.lang) end end, 5000)

getVoiceForPed#

Get the configured or auto-detected TTS voice for a ped entity. Uses NPC config if available, falls back to gender-based pool selection.

Syntax
exports['onex-voiceInteraction']:getVoiceForPed(entity)
NameTypeDescription
entitynumberPed entity handle

Returns: { success = true, data = { voice, gender, stability, similarityBoost, cached, isDefault } }

FieldTypeDescription
voicestringVoice name to use
genderstring"male" or "female"
stabilitynumber | nilElevenLabs stability value, or nil for Edge TTS voices
similarityBoostnumber | nilElevenLabs similarity boost, or nil for Edge TTS voices
cachedbooleantrue if result was served from cache
isDefaultbooleantrue if no NPC config matched and fallback voice was used

Results are cached per entity using a stable key (network ID + model hash). Default-fallback results are not cached so the next call retries after NPC config loads.

Your Script
local r = exports['onex-voiceInteraction']:getVoiceForPed(pedHandle) if r.success then print("Voice:", r.data.voice) print("Gender:", r.data.gender) print("Cached:", r.data.cached) end

clearVoiceCache#

Clear the voice assignment cache for a specific ped or all peds. Forces re-detection on the next speak or getVoiceForPed call.

Syntax
exports['onex-voiceInteraction']:clearVoiceCache(entity)
NameTypeDescription
entitynumberPed entity handle, or omit to clear all cached entries

Returns: { success = true, data = { cleared = 1 } }

Your Script
-- Clear for one ped(forces re-detection next speak) exports['onex-voiceInteraction']:clearVoiceCache(pedHandle) -- Clear all cached voice assignments exports['onex-voiceInteraction']:clearVoiceCache()

Last updated 3 months ago

Quick Links

All DocumentationOur Products