Animation prop editor (tm.animeditor)
Client side only. The in-world side of placing a prop on a ped while an animation plays: a gizmo toolbox (camera, frame maths, bone anchor) and the prop editor an animation picker uses. It needs tm.gizmo, tm.freecam and tm.anim.
-- run in a thread, it blocks until the user applies or cancels
local prop, err = tm.animeditor.editProp{ anim = anim, props = props, index = 1, model = 'a_c_dog' }
if prop then
-- { bone, x, y, z, rx, ry, rz }
elseif err then
-- a failure: err is a translated message
else
-- cancelled (Backspace or Esc): nil and no message
endThe preview ped plays the clip, held still on one frame (left / right scrub through it), the props are attached the way an emote player attaches them, and an invisible anchor on the edited prop's bone gives the bone's world matrix. The gizmo edits a world pose built from anchor x local offset. Each edit is converted back into the bone-local offset and rotation that AttachEntityToEntity takes, which are the numbers saved with the clip.
editProp(data)
| Field | Description |
|---|---|
anim | Anything tm.anim.normalize accepts, with a dict and a clip. |
props | The clip's props (tm.anim.props list: model, bone, x, y, z, rx, ry, rz). |
index | Which prop to edit. |
model | Optional ped model for the preview (an animal, say). Without it the preview is a clone of the player. |
Returns the result table, or nil. A cancel returns nil alone. A failure returns nil and a reason (a translated string, the animeditor.err.* keys): the editor is already open, nothing to edit, the animation library missing, an incomplete prop, an unknown dictionary, no preview ped, the clip cannot play, a model that does not load, no anchor, or an error in the editor loop.
Controls: LMB drag, W move, R rotate, Q world / local, B grid, Up / Down change bone, Left / Right scrub the clip, Enter apply, Backspace cancel, V freecam, F swaps flying and dragging while the freecam is on, hold RMB to look.
While open the editor holds tm.inputlock. Everything it created (ped, props, anchor, camera, help card, gizmo, lock) is removed on apply, cancel, an error and when the resource stops. If the game places the prop differently than the maths expects, a warning toast asks the user to check the preview.
Toolbox
| Call | Description |
|---|---|
cameraHelp(withLook?) | The camera lines of the help card (joined with <br>). |
cameraFrame(origin, refresh) | One frame of freecam and cursor handling for a gizmo editor. Returns true while the mouse drives the camera. |
previewFrame(origin, refresh) / previewEnd() | Freecam handling for previews that have no cursor. |
endCamera() | Stops the freecam and closes the gizmo. |
lockControls() | Disables everything but chat and push to talk for one frame. |
newMatrix() / gizmo(buffer, frame, id) / readMatrix(buffer) / stopGizmo() | Show the gizmo on a world frame every frame, learn whether it was dragged and read the frame back. The buffer is opaque. |
entityFrame(entity) | { right, fwd, up, pos } of an entity. |
toWorld(boneFrame, offset) / toOffset(boneFrame, worldFrame) | Convert between a bone-local { pos, rot } and a world frame. Rotations use GTA's order (Rz * Rx * Ry). |
frameDifference(a, b) | Smallest axis agreement (1 is identical) and the distance. |
math | { toWorld, toOffset, eulerToAxes, axesToEuler } for tests. |
spawnPed(model?, shift?) | A ghost ped in front of the player. |
createObject(hash) / createAnchor() / attach(entity, ped, bone, pos, rot) / destroy(entity) | Entity helpers. |
boneLabel(bone) / cycleBone(current, step) | The bone list the editor offers. |
isEditing() / setEditing(state) / reset() | Editor state. reset puts everything back if an edit threw. |