3D Text UI

A lightweight, optimized standalone script for rendering 3D interactive text labels in the world. It features a dual-loop automatic culling system for high performance, proximity scaling, and support for "tap" and "hold" interactions with visual progress tracking.

⚙️ Data Structures

Before using the functions, understand the data tables used to configure an interaction point.

The Main Configuration Table

This table defines where the text is and how it behaves.

Property

Type

Default

Description

coords

vector3

Required

The world coordinates where the text should appear.

options

table

Required

A list of interaction options (see below).

distance

float

2.5

The distance at which the UI switches to "Full" mode (interaction enabled).

maxDistance

float

5.0

The max distance at which the text is visible at all.

scale

float

1.0

Scaling factor for the UI element.

arc

boolean

false

Visual flag passed to UI (optional style preference).

The Options Table

The options list contains the specific inputs available to the player. Note: Callbacks are now defined directly inside each option via the action property.

options = {
    { 
        label = "PICK UP",          -- The action text displayed
        key = 38,                   -- The FiveM Control Index (38 is E)
        keyName = "E",              -- (Optional) The visual key name. Falls back to Lib47.Keys if omitted.
        action = function()         -- The function triggered upon interaction
            print("Item picked up!")
        end,
        isVisible = function()      -- (Optional) Determines if the option shows up at all
            return true 
        end,
        canInteract = function()    -- (Optional) If false, the option is visible but disabled/grayed out
            return true 
        end
    },
    { 
        label = "INSPECT", 
        key = 74,                   -- 74 is H
        keyName = "H",
        hold = 3,                   -- (Optional) Seconds button must be held to trigger
        action = function()
            print("Inspected!")
        end
    }
}

🛠️ API Reference

This script exposes functions and assigns them to the global Lib47 table. It utilizes an automatic slow culling loop (checking within 30.0 units) and a fast interaction loop, meaning you no longer need to check distances manually in your own threads.

1. RegisterTextUi3d (Static Mode)

Best for static, permanent locations (e.g., Shops, Duty points, ATMs). You register it once, and the script's internal culling handles the rest.

  • Usage: Lib47.RegisterTextUi3d(data)

  • Returns: string (The Interaction ID, derived from coordinates).

2. ShowTextUi3d (Dynamic/Immediate Mode)

Best for dynamic entities (like dropping an item on the ground). This registers the point temporarily. If you walk away, it will eventually be culled out unless updated.

  • Usage: Lib47.ShowTextUi3d(data)

  • Returns: string (Interaction ID).

3. HideTextUi3d & RemoveTextUi3d

Hides or completely removes an interaction point.

  • Usage: Lib47.HideTextUi3d(id) or Lib47.RemoveTextUi3d(id)


📝 Code Examples

Example A: Static Location (Register Mode)

Use this for permanent locations. Run this code once (e.g., at resource start). You do not need a loop.

Example B: Dynamic State & Conditional Logic

Use the isVisible and canInteract functions to dynamically change how the text behaves based on the player's state (e.g., job, money, or items).

Example C: Using Exports directly

If you do not use the Lib47 global wrapper, you can use the resource exports directly via the Interface wrapper.

Last updated