FiveM Animationen und Props: TaskPlayAnim Flags, an Knochen anhängen, löschen

Spiele Animationen ab und hänge Props in FiveM Lua an: RequestAnimDict, TaskPlayAnim Flags 1, 16, 32 und 49, ClearPedTasks, AttachEntityToEntity an einen Knochen, Szenarien und Bereinigung.

Du möchtest, dass ein Spieler einen Kaffee trinkt, ein Telefon hält oder ein Werkzeug benutzt: eine Animation, oft mit einem Prop in der Hand. Falsch gemacht, macht die Animation nichts, der Prop schwebt bei den Füßen des Spielers oder bleibt für immer in der Welt. Dieser Leitfaden zeigt die funktionierende Sequenz und die Bereinigung.

Laden, spielen, löschen

Eine Animation lebt in einem Wörterbuch. Das Wörterbuch muss geladen werden, bevor du daraus spielst:

lua
local function playAnim(ped, dict, anim, flag, duration)
    RequestAnimDict(dict)
    while not HasAnimDictLoaded(dict) do
        Wait(0)
    end
    TaskPlayAnim(ped, dict, anim, 8.0, -8.0, duration or -1, flag or 0, 0.0, false, false, false)
end

Wenn HasAnimDictLoaded nie wahr ist, ist der Wörterbuch-Name falsch und diese Schleife hängt fest, also füge einen Timeout hinzu, wenn der Name aus der Konfiguration kommt. Mit ox_lib, eine Zeile ersetzt die Schleife:

lua
lib.requestAnimDict('mp_player_inteat@burger')

TaskPlayAnim nimmt den Ped, Wörterbuch, Animation, Blend in, Blend out, Dauer in ms (-1 = bis gestoppt), die Flag, und eine Wiedergaberate. Geben Sie das Wörterbuch frei, wenn Sie mit RemoveAnimDict(dict) fertig sind.

Die Animations-Flags

Die Flag ist eine Bitmaske, daher addieren sich Werte. Die, die du verwendest:

Flag Effekt
0 Einmal spielen, Spieler kann sich nicht bewegen
1 Schleife
16 Nur Oberkörper, Beine gehen weiter
32 Spieler behält Kontrolle
49 1 + 16 + 32: Schleife, Oberkörper, steuerbar

Für eine Animation in der Hand (Telefon, Getränk, Zigarette) ist 49 normalerweise die Wahl: Sie schleifen, nur der Oberkörper wird animiert und der Spieler kann immer noch gehen. Für eine einmalige Aktion, bei der der Spieler still stehen sollte, verwenden Sie 0, oder 1, wenn es loopen sollte.

Animation stoppen

lua
local ped = PlayerPedId()
ClearPedTasks(ped)                 -- stop and let the ped blend out
-- or, if it is stuck:
ClearPedTasksImmediately(ped)      -- cut instantly, can look abrupt
StopAnimTask(ped, dict, anim, 1.0) -- stop only that animation

Verwende StopAnimTask, wenn mehrere Dinge auf dem Ped laufen, da ClearPedTasks auch das Gehen oder das Szenario darunter abbricht. ClearPedTasksImmediately repariert einen steckenden Ped, kann aber auch aus Fahrzeugen schnappen, also halte es für die Wiederherstellung.

Ein Prop in der Hand

Ein Prop ist ein Objekt, das du erstellen und an einen Knochen des Peds anhängst. Die Abfolge: Modell laden, Objekt erstellen, anhängen, Animation spielen.

lua
local prop

local function attachProp(ped, model, bone, x, y, z, rx, ry, rz)
    local hash = joaat(model)
    RequestModel(hash)
    while not HasModelLoaded(hash) do Wait(0) end

    local coords = GetEntityCoords(ped)
    prop = CreateObject(hash, coords.x, coords.y, coords.z + 0.2, true, true, false)

    AttachEntityToEntity(
        prop, ped, GetPedBoneIndex(ped, bone),
        x, y, z, rx, ry, rz,
        true, true, false, true, 1, true
    )
    SetModelAsNoLongerNeeded(hash)
    return prop
end

Die Teile:

  • CreateObject(model, x, y, z, isNetwork, netMissionEntity, doorFlag): Pass isNetwork = true, wenn andere Spieler den Prop sehen sollten, was normalerweise das ist, was du für etwas in einer Hand möchtest.
  • GetPedBoneIndex(ped, boneId) konvertiert eine Knochen-ID wie 28422 (rechte Hand-Platzierung) oder 18905 (linke Hand) zu einem Index. Schlag die Knochen-ID-Liste für andere nach.
  • x, y, z und rx, ry, rz sind die Offsets und Rotation relativ zum Knochen. Diese müssen pro Prop abgestimmt werden; es gibt keine Abkürzung, also ändere einen Wert und teste.
  • Die Booleaner nach der Rotation sind sanfte Befestigung, Kollision und ähnliche Flags. Kollision false verhindert, dass der Prop den Ped herumschubst.

Setz es zusammen

lua
local function eatBurger()
    local ped = PlayerPedId()
    attachProp(ped, 'prop_cs_burger_01', 28422, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0)
    lib.requestAnimDict('mp_player_inteat@burger')
    TaskPlayAnim(ped, 'mp_player_inteat@burger', 'mp_player_int_eat_burger', 8.0, -8.0, 3000, 49, 0.0, false, false, false)
    Wait(3000)
    ClearPedTasks(ped)
    deleteProp()
end

Wenn der Prop in der Hand falsch aussieht, repariere zuerst die Offsets, dann den Knochen. Wenn ein anderer Animationsname nicht in einem Wörterbuch existiert, macht TaskPlayAnim stillschweigend nichts, also überprüfe das Paar (die exakten Wörterbuch- und Animationsnamen, in Kleinbuchstaben wie geschrieben).

Lösche den Prop

Räume immer auf. Ein Prop, der nicht gelöscht wird, bleibt in der Welt, immer noch an einen Ped angehängt, der ihn nicht mehr hält:

lua
function deleteProp()
    if prop and DoesEntityExist(prop) then
        DetachEntity(prop, true, true)
        DeleteEntity(prop)
    end
    prop = nil
end

AddEventHandler('onResourceStop', function(resource)
    if resource ~= GetCurrentResourceName() then return end
    deleteProp()
    ClearPedTasks(PlayerPedId())
end)

Lösche auch den Prop beim Tod und wenn der Spieler die Animation verlässt, nicht nur auf dem glücklichen Weg. Durchgesickerte Props sind eine klassische Quelle von "Objekten überall" und einem langsamen Server; siehe resmon high ms.

Szenarien

Für stehende Animationen, die ihre eigenen Props enthalten, wie Lehnen, Rauchen oder auf einer Zwischenablage schreiben, verwende stattdessen ein Szenario:

lua
local ped = PlayerPedId()
TaskStartScenarioInPlace(ped, 'WORLD_HUMAN_CLIPBOARD', 0, true)

-- later
ClearPedTasks(ped)

Die Argumente sind der Ped, der Szenarioname, eine Verzögerung in ms (0 für keine) und ob die Eingabeanimation abgespielt werden soll. Szenarien hängen an und räumen ihren Prop für dich auf, und sie sind die einfachste Option, wenn die Animation nicht gehalten werden muss, während man geht.

Für eine vorgefertigte Version von Animation plus Prop plus Fortschrittsbalken nimmt ox_lib's lib.progressBar anim und prop-Optionen an; siehe notifications and progress bars und Wait and threads für die Wartungsgewohnheiten hinter den oben genannten Schleifen.

Checkliste

Symptom Lösung
Animation macht nichts Fordere das Wörterbuch an und warte erst auf HasAnimDictLoaded
Schleife hängt beim Laden Der Wörterbuch-Name ist falsch; füge einen Timeout hinzu
Spieler an Ort und Stelle eingefroren Flag 0 oder 1 blockiert Bewegung; verwende 49, um die Kontrolle zu behalten
Prop bei den Füßen, nicht der Hand Falscher Knochen oder kein AttachEntityToEntity; überprüfe GetPedBoneIndex
Prop schief in der Hand Stimme die x, y, z und Rotations-Offsets ab
Props in der Welt hinterlassen DeleteEntity(prop) beim Ende, Tod und Ressourcenstopp
Ped in einer Pose stecken ClearPedTasks oder als letzter Ausweg ClearPedTasksImmediately

Kurze Antworten

Warum wird meine Animation nicht abgespielt?

Das Animationswörterbuch wurde noch nicht geladen. Rufe RequestAnimDict auf, warte, bis HasAnimDictLoaded wahr ist, und rufe erst dann TaskPlayAnim auf. Mit ox_lib macht lib.requestAnimDict(dict) das für dich.

Welche TaskPlayAnim-Flag sollte ich verwenden?

Verwende 1 zum Loopen, 16, um nur auf dem Oberkörper zu spielen, 32, damit der Spieler die Kontrolle behält, und 49 für Loop plus Oberkörper plus steuerbar. Dies sind die häufigen Kombinationen für Animationen, die du beim Gehen hältst.

Wie entferne ich einen Prop nach der Animation?

Rufe DeleteEntity(prop) auf, wenn die Animation endet oder das Skript stoppt, und geben Sie das Modell mit SetModelAsNoLongerNeeded frei. Props, die zurückgelassen werden, häufen sich in der Welt an.

Scripts ohne dieses Problem

Hookah SystemPlatzierbare Shishas und Lounge-Möbel mit über 50 Aromen und Effekten.Script ansehen →Vape SystemÜber 50 Vapes mit Aromen, Rauch und Effekten — von Mango bis Super-Speed.Script ansehen →Super Leaf BlowerEin Laubbläser, der Spieler, Autos, NPCs und Props wegpustet. Läuft auf jedem Framework.Script ansehen →

Weiterlesen