NR_EmoteMenu
A full-featured emote menu with a custom React tablet UI, 700+ animations, thumbnail previews, emote placement, synced emotes with consent, quick-access favorites, walking styles, expressions, props, and full addon support.
Features
- Custom tablet UI - Dark glassmorphism React interface with a realistic tablet bezel and configurable theme color
- 700+ animations - Emotes, dances, props, synced emotes, walking styles, expressions, and scenarios
- Thumbnail previews - Visual thumbnails for each emote with animated GIF support
- Emote placement - Place emotes at a specific location with scroll-wheel rotation and shift-height adjustment
- Walk-to placement - Player walks to the placed location instead of teleporting, with a 4-second timeout fallback
- Synced emotes - Request shared emotes with nearby players who can accept or decline
- Quick-access favorites - Drag-and-drop emotes to configurable quick-access slots
- Walking styles - Apply persistent walk cycle overrides
- Facial expressions - Apply facial mood overrides
- Prop emotes - Emotes that attach prop objects to the player
- Scenario support - Play GTA scenario animations
- Vehicle emotes - Perform emotes while seated in vehicles
- Chat commands - Play emotes, walks, and expressions via chat commands
- Keybinds - Configurable hotkeys for menu, cancel, hands up, point, crouch, and ragdoll
- Hands up & pointing - Dedicated keybinds with toggle or hold mode
- Crouch & stance - Stealth and crouch stance system
- Particle effects - Auto-play particle effects on emotes that support them
- KVP persistence - Favorites and walk styles persist across sessions using FiveM key-value pairs
- Addon system - Add custom emotes, dances, props, walks, and more via addon files
- Backward compatible - Supports legacy scully_emotemenu command/export API
- Auto-framework detection - Works with ESX, QBCore, QBX, and standalone
- Security hardened - Server-authoritative sync emote validation, consent-based requests, anti-exploit protection
- Thumbnail capture tool - Admin command to automatically capture and store emote thumbnails
Dependencies
| Resource | Description | Required |
|---|---|---|
| ESX / QBCore / QBX / Standalone | Any supported framework (auto-detected) | Optional |
| ox_lib | Notifications (if using QBX) | Optional |
NR_EmoteMenu works standalone with zero required dependencies. Framework detection is automatic and only used for notifications and death-state checking. The script falls back gracefully if no framework is detected.
Installation
Step 1: Download
Download NR_EmoteMenu from your Tebex purchase and extract it to your resources folder:
server/
└── resources/
└── [echo]/
└── NR_EmoteMenu/
Step 2: server.cfg
Add the resource to your server configuration:
ensure NR_EmoteMenu
If using a framework, ensure your framework resource (qbx_core, qb-core, or es_extended) starts before NR_EmoteMenu.
Step 3: Configuration
Edit config.lua to set your preferred keybinds, theme color, and feature toggles.
Step 4: Restart
Restart your server to load the resource. No database setup required.
How It Works
1. Opening the Menu
Press F5 (default) or type /em or /emotemenu in chat. A tablet-style UI opens showing all available emote categories.
2. Browsing Emotes
Emotes are organized into categories: Emotes, Dances, Props, Synced, Walks, Expressions, and Scenarios. Each emote shows a thumbnail preview if available. Use the search bar to find emotes by name.
3. Playing an Emote
Click any emote to play it. The menu closes and the animation begins. To cancel, press the cancel key (X by default) or start a new emote.
4. Emote Placement
Some emotes support placement mode. When activated, a ghost preview appears that you can position:
- Mouse - Move the placement location
- Scroll wheel - Rotate the emote direction
- Shift + scroll - Adjust height
- E / Left click - Confirm placement
- Backspace - Cancel
Your character walks to the placed location. If they can't reach it within 4 seconds, they teleport there instead.
5. Synced Emotes
Synced emotes require a nearby partner. When you start a synced emote, a request is sent to the nearest player within range. They receive a prompt to accept or decline. Both players must consent before the animation plays.
6. Quick-Access Favorites
Drag emotes from the menu to your quick-access bar (up to 10 slots, configurable). Favorites persist across sessions. Access them without opening the full menu.
7. Walking Styles
Apply a walk style from the Walks category. The walk persists until you change it or reset it. Use /w reset in chat to return to the default walk.
8. Chat Commands
/e dance -- Play the "dance" emote
/e cancel -- Cancel current emote
/w gangster -- Set walking style
/w reset -- Reset walking style
/f happy -- Set facial expression
Configuration
Appearance & Framework
Config.theme = '#00FFFF' -- NUI accent colour (any valid CSS hex)
Config.framework = 'auto' -- 'auto' | 'esx' | 'qbcore' | 'qbox' | 'standalone'
The theme color controls buttons, highlights, gradients, and glow effects throughout the UI. Any valid hex color works, including shorthand (#0FF) and 8-digit (#AA00FFFF) formats.
Keybinds
Config.menuKey = 'F5' -- Open emote menu
Config.cancelKey = 'X' -- Cancel current emote
Config.ptfxKey = 'G' -- Toggle particle effects
Config.handsupKey = 'H' -- Hands up
Config.handsupToggle = true -- true = toggle, false = hold
Config.stanceKey = 'LCONTROL' -- Crouch / stealth stance
Config.crouchOnly = false -- true = skip stealth stance
Config.pointKey = 'B' -- Point finger
Config.ragdollKey = 'U' -- Ragdoll
Set any keybind to '' (empty string) to disable it.
Chat Commands
Config.menuCmds = { 'em', 'emotemenu' } -- Commands to open the menu
Config.emoteCmds = { 'e', 'emote', 'eplay' } -- Commands to play an emote
Config.walkCmds = { 'w', 'walk' } -- Commands to set walk style
Config.faceCmds = { 'f', 'face' } -- Commands to set expression
Feature Toggles
Config.cooldownMs = 250 -- Milliseconds between emote uses
Config.vehicleEmotes = true -- Allow emotes in vehicles
Config.blockWeapons = false -- Block emotes when holding a weapon
Config.blockAimFire = true -- Suppress aim/fire while emoting
Config.walkAbuseFix = true -- Patch sprint clipset exploit
Config.autoPtfx = true -- Auto-play particle effects
Config.cancelOnDeath = true -- Auto-cancel emote on death
Config.favoriteSlots = 5 -- Quick-access slots (1-10)
Config.syncRange = 3.0 -- Max distance for sync emote requests
Content Filters
Config.gangContent = false -- Show gang-tagged emotes
Config.socialContent = false -- Show social-tagged emotes
Config.syncEmotes = true -- Enable synced emotes
Disabling gangContent or socialContent removes emotes tagged with those categories from the registry. Disabling syncEmotes prevents synced dance emotes from being generated.
Addon System
Add custom emotes by creating Lua files in the addons/ folder. All files matching addons/*.lua are automatically loaded.
Addon Structure
-- addons/my_emotes.lua
NR_AddonEmotes = NR_AddonEmotes or {}
NR_AddonDances = NR_AddonDances or {}
NR_AddonProps = NR_AddonProps or {}
NR_AddonSynced = NR_AddonSynced or {}
NR_AddonWalks = NR_AddonWalks or {}
NR_AddonExpressions = NR_AddonExpressions or {}
NR_AddonScenarios = NR_AddonScenarios or {}
NR_AddonEmotes['myemote'] = {
label = "My Custom Emote",
dict = "anim@amb@nightclub@dancers@",
anim = "hi_dance_facedj_17_v2_male^4",
loop = true,
movable = false,
}
Emote Entry Fields
| Field | Type | Description |
|---|---|---|
label |
string | Display name in the menu |
dict |
string | Animation dictionary |
anim |
string | Animation name within the dictionary |
loop |
boolean | Whether the emote loops continuously |
movable |
boolean | Allow movement while emoting |
category |
string | Override category (emote, dance, prop, sync, walk, expression, scenario) |
gang |
boolean | Tag as gang content (filtered by Config.gangContent) |
social |
boolean | Tag as social content (filtered by Config.socialContent) |
Thumbnail System
NR_EmoteMenu supports visual thumbnails and animated GIF previews for every emote. Thumbnails are stored in a thumbnails.json file that ships with the resource.
Capturing Thumbnails (Admin)
Server admins can use the /shootemotes command to automatically capture thumbnails for all emotes. The command:
- Teleports the player to a capture location
- Forces consistent lighting (extra sunny weather, noon time)
- Cycles through each emote, capturing a still frame and animated preview
- Saves results to
thumbnails.jsonon the server
Requires the NR_EmoteMenu.shootemotes ACE permission (granted to group.admin by default).
Once thumbnails are captured, the thumbnails.json file transfers with the resource. Other servers using the same resource will have the same thumbnails without needing to re-capture.
Synced Emote Security
The synced emote system is server-authoritative to prevent exploits:
- Consent required - Target player must press E to accept or Backspace to decline
- Server validation - Emote keys are validated against the server-side registry before storing requests
- Distance checks - Both request and accept are distance-verified on the server
- Key-based lookup - Clients receive emote keys (not raw animation data) and look up from their local registry
- Request expiry - Pending requests expire after 15 seconds
- No forced emotes - Legacy compatibility events are local-only and cannot be triggered remotely
File Structure
NR_EmoteMenu/
├── config.lua -- All configuration (editable)
├── emotes_config.lua -- Built-in emote definitions (editable)
├── addons/ -- Custom addon emotes (editable)
│ └── example.lua
├── bridge/
│ └── loader.lua -- Framework auto-detection (editable)
├── shared/
│ └── core.lua -- Shared utilities (escrowed)
├── client/
│ └── main.lua -- Client logic (escrowed)
├── server/
│ └── sync.lua -- Server sync & thumbnails (escrowed)
├── web/
│ └── dist/ -- Built React UI
└── thumbnails.json -- Captured emote thumbnails
Exports & API
Notification Override
Override the default notification system with your own handler:
exports['NR_EmoteMenu']:onNotify(function(kind, msg)
-- Your custom notification logic
end)
Backward Compatibility
NR_EmoteMenu supports legacy scully_emotemenu commands and events for drop-in compatibility with scripts that use the older API:
-- These commands work automatically:
/e dance
/emote sit
/eplay wave
Troubleshooting
Menu not opening
- Check F8 console for errors
- Verify the
web/dist/folder exists and contains built files - Ensure
Config.menuKeyis set to a valid key - Try the chat command
/emas a fallback
Theme color not applying
- Use a standard 6-digit hex code (e.g.
#00FFFF) - Shorthand (#0FF) and 8-digit (#AA00FFFF) formats are also supported
- Restart the resource after changing
Config.theme
Emote not playing
- Check if the animation dictionary exists (some custom emotes require streamed assets)
- Verify the emote key matches exactly in the config
- Check if
Config.blockWeaponsis preventing the emote while armed - Ensure cooldown has elapsed (
Config.cooldownMs)
Synced emote not working
- Ensure
Config.syncEmotes = true - Both players must be within
Config.syncRangedistance - Target player must accept the request (press E)
- Requests expire after 15 seconds
Thumbnails not showing
- Ensure
thumbnails.jsonexists in the resource root - Run
/shootemotesas an admin to capture thumbnails - Thumbnails are requested on menu open — check server console for errors
Drag to favorites not working
- Click and hold on the emote card, then drag to a quick-access slot
- Ensure
Config.favoriteSlotsis set to at least 1
Walk style not persisting
- Walk styles are saved via FiveM KVP (key-value pairs) and should persist automatically
- If using a shared server, ensure KVP storage is not being cleared by other resources
- Use
/w resetthen reapply to refresh the saved value
Support
For paid script support, open a ticket in our Discord server for priority assistance.