> ## Documentation Index
> Fetch the complete documentation index at: https://docs.9am.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# FiveM Text UI Script

> 9AM TextUI is a free animated Text UI replacement for FiveM with 3D world-space and screen-space rendering, smooth morphing animations, and ox_lib override support.

## 9AM TextUI overview

9AM TextUI is a free animated Text UI replacement for FiveM that supports both 3D world-space and screen-space rendering with smooth morphing animations. It automatically overrides `ox_lib`'s Text UI so all existing scripts use it without code changes.

## Public features

* 3D world prompts rendered at world coordinates with camera projection tracking
* Classic screen-anchored overlay mode
* Drop-in `ox_lib` override for `lib.showTextUI` / `lib.hideTextUI`
* Sphere, box, and poly zone types via `ox_lib`
* Distance-based animation that expands when near and collapses into a dot when far
* Configurable accent color
* Free and open source

## Dependencies

* `ox_lib`

## Compatibility and editions

| Type          | Details    |
| ------------- | ---------- |
| Compatibility | Standalone |
| Price         | **Free**   |

## Config

```lua theme={null}
-- config.lua
Config.PrimaryColor = '#f7e472'

Config.Zones = {
  {
    id = 'management-menu',
    text = 'Open Management',
    key = 'E',
    coords = vec3(-34.9118, -1102.1649, 26.4224),
    displayDist = 10.0,
    nearDist = 2.0,
    offset = vec3(0.0, 0.0, -0.6),
  },
}
```

### Zone options

| Option        | Type      | Default       | Description                             |
| ------------- | --------- | ------------- | --------------------------------------- |
| `id`          | `string`  | —             | Unique identifier (required)            |
| `text`        | `string`  | —             | Prompt label                            |
| `key`         | `string`  | `""`          | Key hint in the badge (e.g. `'E'`)      |
| `coords`      | `vec3`    | —             | World position                          |
| `displayDist` | `number`  | `10.0`        | Distance at which the prompt is visible |
| `nearDist`    | `number`  | `2.0`         | Distance at which the prompt expands    |
| `offset`      | `vec3`    | `(0, 0, 1)`   | Offset from coords for display anchor   |
| `type`        | `string`  | `'sphere'`    | Zone type: `sphere`, `box`, or `poly`   |
| `radius`      | `number`  | `displayDist` | Zone radius (sphere only)               |
| `size`        | `vec3`    | —             | Zone dimensions (box only)              |
| `rotation`    | `number`  | —             | Zone rotation (box only)                |
| `points`      | `table`   | —             | Zone vertices (poly only)               |
| `thickness`   | `number`  | —             | Zone height (poly only)                 |
| `debug`       | `boolean` | `false`       | Draw debug zone outline                 |

## Exports

### 3D World TextUI

```lua theme={null}
-- Create
exports['9am-textui']:createTextUI('shop-door', {
  text = 'Open Shop',
  key = 'E',
  coords = vec3(250.0, -850.0, 29.5),
  displayDist = 10.0,
  nearDist = 2.0,
})

-- Update (partial, only changed fields)
exports['9am-textui']:updateTextUI('shop-door', { text = 'Closed' })

-- Remove
exports['9am-textui']:removeTextUI('shop-door')
```

### Screen Overlay TextUI

```lua theme={null}
-- Show (key is parsed from [X] prefix)
exports['9am-textui']:showOverlayTextUI('[E] Open Menu')

-- Show at world coords
exports['9am-textui']:showOverlayTextUI('[E] Open Menu', {
  coords = vec3(100.0, 200.0, 30.0),
})

-- Hide
exports['9am-textui']:hideOverlayTextUI()

-- Check state
local isOpen = exports['9am-textui']:isOverlayTextUIOpen()
```

### ox\_lib override

The included `override.lua` replaces `lib.showTextUI` / `lib.hideTextUI` globally. Two ways to set it up:

**Option A — Add directly to ox\_lib** (recommended, applies to all resources automatically):

Copy `override.lua` into `ox_lib/imports/` (or any loaded path), then add it to ox\_lib's `fxmanifest.lua`:

```lua theme={null}
files { '@9am-textui/override.lua' }
client_scripts { '@9am-textui/override.lua' }
```

**Option B — Per resource:**

Add to the target resource's `fxmanifest.lua`:

```lua theme={null}
files { '@9am-textui/override.lua' }
client_scripts { '@9am-textui/override.lua' }
```

After either setup, these calls route through 9am-textui automatically:

```lua theme={null}
lib.showTextUI('[E] Interact')
lib.hideTextUI()
lib.isTextUIOpen()
```

## Advanced zone types

### Box

```lua theme={null}
exports['9am-textui']:createTextUI('garage', {
  text = 'Enter Garage',
  key = 'E',
  type = 'box',
  coords = vec3(200.0, -800.0, 30.0),
  size = vec3(10.0, 6.0, 4.0),
  rotation = 45.0,
  displayDist = 15.0,
})
```

### Poly

```lua theme={null}
exports['9am-textui']:createTextUI('park', {
  text = 'Rest Area',
  key = 'G',
  type = 'poly',
  points = {
    vec3(100.0, 200.0, 30.0),
    vec3(110.0, 200.0, 30.0),
    vec3(110.0, 210.0, 30.0),
    vec3(100.0, 210.0, 30.0),
  },
  thickness = 4.0,
  displayDist = 20.0,
})
```

Poly zones don't require `coords` — defaults to the centroid of the points.

## Example

```lua theme={null}
CreateThread(function()
  exports['9am-textui']:createTextUI('atm_legion', {
    text = 'Use ATM',
    key = 'E',
    coords = vec3(149.0, -1040.0, 29.4),
    displayDist = 5.0,
    nearDist = 1.5,
    offset = vec3(0.0, 0.0, 0.5),
  })
end)

-- Dynamic update
RegisterNetEvent('bank:client:toggleATM', function(enabled)
  if enabled then
    exports['9am-textui']:updateTextUI('atm_legion', { text = 'Use ATM', key = 'E' })
  else
    exports['9am-textui']:updateTextUI('atm_legion', { text = 'Out of Service', key = '' })
  end
end)

-- Cleanup
AddEventHandler('onResourceStop', function(res)
  if res == GetCurrentResourceName() then
    exports['9am-textui']:removeTextUI('atm_legion')
  end
end)
```

## Best for

Choose this script if you want:

* A visually polished Text UI with smooth animations at no cost
* 3D world-space prompts that track camera projection
* A seamless `ox_lib` Text UI replacement without changing existing code

## Download link

[Open TextUI in the store](https://9am.dev/scripts/escrow/3d-text-ui)
