Skip to content

Latest commit

 

History

5 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

noted_propattacher

In-game debug tool for finding prop attachment offsets and rotations — on ped bones or vehicle bones — with a draggable 3D gizmo, a freecam, nearest-bone recalibration, and copy-paste code export.

Built for tuning AttachEntityToEntity values visually instead of guessing numbers and restarting.


Commands

Command What it does
/propattacher Open / minimize the tool (keeps the current target mode)
/propattacher ped Target the player ped
/propattacher veh Target the vehicle you're sitting in, or the nearest one within 20m
/propattacher veh near Target the nearest other vehicle (ignores the one you're in)

Running the command while the tool is open in the same mode minimizes it. Running it with a different mode (or veh near) switches target — any in-progress placement is cancelled.

Workflow

  1. SPAWN tab — type a prop model (e.g. w_lr_rpg) and hit SPAWN. Pick a bone from the list (searchable), or type an index/name directly. In vehicle mode the bone list is filtered to bones that actually exist on the targeted vehicle model.
  2. ADJUST tab — position the prop:
    • Drag an arrow to move along that axis. Drag a ring to rotate around it.
    • Hold RMB outside the panel for freecam: WASD to fly, mouse to look, Shift = fast, Q/E = up/down. Release RMB to get the cursor back — the camera stays where you left it.
    • Scroll wheel nudges Z. Nudge buttons / direct number entry / step-size presets also work.
    • E confirms, Backspace minimizes.
  3. ⟳ RECAL — finds the bone closest to where the prop currently sits and re-attaches to it without the prop moving in the world. The result is applied as a live preview with measured accuracy (Δpos / Δrot) shown in the popup — keep it or revert.
  4. CONFIRM saves the placement to the attached list. Spawn the next prop or:
  5. ATTACHED tab — click any entry to pull it back into live editing (works across modes — a vehicle attachment re-targets its vehicle automatically). During an edit, CANCEL restores the original attachment instead of deleting the prop. ✕ deletes an entry.
  6. EXPORT tab — generate ready-to-paste Lua in two formats:
    • Full AttachEntityToEntity blocks (model loading included)
    • Compact {model, bone, pos, rot} tables

Ped exports use GetPedBoneIndex(ped, <id>); vehicle exports use GetEntityBoneIndexByName(veh, "<name>") with the correct isPed flag.

Files

fxmanifest.lua
shared/bones.lua        -- ped bone list (tags), vehicle bone list (names), ped presets
client/client.lua       -- everything: gizmo, freecam, placement, recal, NUI callbacks
html/                   -- NUI panel (index.html, css/style.css, js/app.js)

Add to your server config: ensure noted_propattacher. No dependencies, client-side only — props are spawned locally and are not networked to other players as persistent attachments.

Technical notes (read before touching the math)

  • Rotation order is ROT_YZX. All AttachEntityToEntity calls here pass rotationOrder = 1, which the engine applies as intrinsic Y→Z→X (M = Ry(roll)·Rz(yaw)·Rx(pitch)). This does not match the common GetEntityRotation(2) ZXY convention. RotFromEuler / EulerFromAxes in client.lua implement the correct chart — every euler↔matrix conversion must go through them. Using the wrong chart was the historical cause of inverted drag axes, dead rotation rings, and recal landing ~45° off.
  • Gizmo axes are derived, not queried. The engine guarantees prop_matrix = bone_frame · R(rotation), so the true attach frame is computed as prop_matrix · R⁻¹ from the prop's live entity matrix. Don't replace this with GetEntityBoneRotation formulas — their convention doesn't match the attach frame.
  • Ring drags compose matrices. A ring drag applies a true rotation about the ring's bone-frame axis and converts back to euler (RotateAboutBoneAxis) — adding degrees to a single euler component only works for the outermost axis under YZX.
  • Recalibrate measures empirically, then converges. The new bone's attach frame is measured by attaching at zero and reading the entity matrix, then a convergence loop corrects offset/rotation from the observed landing spot until Δpos < 1.5cm and Δrot < 0.5°. Two hard-won rules:
    • recalBusy must suspend the placement loop — it re-attaches the prop to the old bone every frame and corrupts measurements taken mid-Wait.
    • Never measure an invisible attached entity — GetEntityMatrix goes stale and silently poisons both the math and its own verification. Reads are validated against GetWorldPositionOfEntityBone (skeleton-fresh) instead of blind-waiting.
  • Cursor rays come from GetWorldCoordFromScreenCoord, which uses the active render camera — correct while the scripted freecam is rendering (a paused freecam keeps rendering) and at any FOV/aspect ratio.
  • Recal debug tracing: set RECAL_DEBUG = false in client.lua to silence the [recal] F8 prints. Leave it on while tuning — iteration 1 should report angErr near zero; if it doesn't, the rotation chart no longer matches the attach flags.

Known limits

  • Rotation extraction has a gimbal singularity at yaw ±90° (rare in practice; recal's convergence loop still bounds the error).
  • Recal accuracy on peds bottoms out around the idle-animation sway (~1cm) — the skeleton literally moves while measuring.
  • Attached-list entries reference live entity handles; props and their parent vehicles don't survive resource restarts or entity despawns (the UI reports and prunes dead entries when you interact with them).

About

Version 1 Fivem Prop Attachment script for developer purposes

Resources

Stars

17 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages