Animations in Noclip mode do not move in sync

--==--==--==--
-- Config
--==--==--==--

config = {
    controls = {
        -- [[Controls, list can be found here : https://docs.fivem.net/game-references/controls/]]
        openKey = 56,     -- [[F2]]
        goUp = 85,        -- [[Q]]
        goDown = 48,      -- [[Z]]
        turnLeft = 34,    -- [[A]]
        turnRight = 35,   -- [[D]]
        goForward = 32,   -- [[W]]
        goBackward = 33,  -- [[S]]
        changeSpeed = 21, -- [[L-Shift]]
    },

    speeds = {
        -- [[If you wish to change the speeds or labels there are associated with then here is the place.]]
        { label = "很慢", speed = 0 },
        { label = "慢速", speed = 0.5 },
        { label = "正常", speed = 2 },
        { label = "快速", speed = 4 },
        { label = "很快", speed = 6 },
        { label = "极快", speed = 10 },
        { label = "极快 v2.0", speed = 20 },
        { label = "最大速度", speed = 25 }
    },

    offsets = {
        y = 0.5, -- [[How much distance you move forward and backward while the respective button is pressed]]
        z = 0.2, -- [[How much distance you move upward and downward while the respective button is pressed]]
        h = 3,   -- [[How much you rotate. ]]
    },

    -- [[Background colour of the buttons. (It may be the standard black on first opening, just re-opening.)]]
    bgR = 0,  -- [[Red]]
    bgG = 0,  -- [[Green]]
    bgB = 0,  -- [[Blue]]
    bgA = 80, -- [[Alpha]]
}

--==--==--==--
-- End Of Config
--==--==--==--

noclipActive = false -- [[Wouldn't touch this.]]

index = 1            -- [[Used to determine the index of the speeds table.]]

-- 加载动画字典
function loadAnimDict(dict)
    RequestAnimDict(dict)
    while not HasAnimDictLoaded(dict) do
        Citizen.Wait(0)
    end
end

Citizen.CreateThread(function()
    buttons = setupScaleform("instructional_buttons")
    currentSpeed = config.speeds[index].speed

    while true do
        Citizen.Wait(0)

        if IsControlJustPressed(1, config.controls.openKey) then
            noclipActive = not noclipActive

            if IsPedInAnyVehicle(PlayerPedId(), false) then
                noclipEntity = GetVehiclePedIsIn(PlayerPedId(), false)
            else
                noclipEntity = PlayerPedId()
            end

            -- 更新本地实体属性
            SetEntityCollision(noclipEntity, not noclipActive, not noclipActive)
            FreezeEntityPosition(noclipEntity, noclipActive)
            SetEntityInvincible(noclipEntity, noclipActive)
            SetVehicleRadioEnabled(noclipEntity, not noclipActive)

            -- if noclipActive and not IsPedInAnyVehicle(PlayerPedId(), false) then
            --     loadAnimDict("skydive@base")
            --     TaskPlayAnim(noclipEntity, "skydive@base", "free_idle", 8.0, 8.0, -1, 1, 0, false, false, false)
            -- else
            --     ClearPedTasks(noclipEntity)
            -- end
        end

        if noclipActive then
            DrawScaleformMovieFullscreen(buttons)

            local yoff = 0.0
            local zoff = 0.0

            if IsControlJustPressed(1, config.controls.changeSpeed) then
                if index ~= 8 then
                    index = index + 1
                    currentSpeed = config.speeds[index].speed
                else
                    currentSpeed = config.speeds[1].speed
                    index = 1
                end
                setupScaleform("instructional_buttons")
            end

            DisableControls()

            if IsDisabledControlPressed(0, config.controls.goForward) then
                yoff = config.offsets.y
            end

            if IsDisabledControlPressed(0, config.controls.goBackward) then
                yoff = -config.offsets.y
            end

            if IsDisabledControlPressed(0, config.controls.turnLeft) then
                SetEntityHeading(noclipEntity, GetEntityHeading(noclipEntity) + config.offsets.h)
            end

            if IsDisabledControlPressed(0, config.controls.turnRight) then
                SetEntityHeading(noclipEntity, GetEntityHeading(noclipEntity) - config.offsets.h)
            end

            if IsDisabledControlPressed(0, config.controls.goUp) then
                zoff = config.offsets.z
            end

            if IsDisabledControlPressed(0, config.controls.goDown) then
                zoff = -config.offsets.z
            end

            local newPos = GetOffsetFromEntityInWorldCoords(noclipEntity, 0.0, yoff * (currentSpeed + 0.3), zoff * (currentSpeed + 0.3))
            local heading = GetEntityHeading(noclipEntity)
            SetEntityVelocity(noclipEntity, 0.0, 0.0, 0.0)
            SetEntityRotation(noclipEntity, 0.0, 0.0, 0.0, 0, false)
            SetEntityHeading(noclipEntity, heading)
            SetEntityCoordsNoOffset(noclipEntity, newPos.x, newPos.y, newPos.z, noclipActive, noclipActive, noclipActive)
        end
    end
end)

--==--==--==--
-- End Of Script
--==--==--==--

I tried to add an animation effect in this Noclip code, but the actual use of it was not what I expected.

  1. Without animation, player can see Noclip’s movement normally.

  2. This is what happens when you use animation

I would like to ask you how this problem is caused and what I can do to solve it.

You know how to fix it?

No, I haven’t found a suitable solution yet. :joy:

Hey, I have faced similar issues,
first what is going on : during animation usage, the position sync gets broken since the game does not expect the player that is doing the animation to actually move with SetEntityCoords or SetEntityCoordsNoOffset ( which is what noclip is doing ), Although the client sees that he is moving, other players dont recognize the new movements
The script that i was trying to do that had the similar issue was this VS Emote Adjuster v2
The fix! which is a very weird fix for this, after trying everything i thought it would fix, The only solution to this is manually syncing the coordinates of that specific player ped that is doing the animation for every nearby clients! i don’t know why it works, but it does!
however keep in mind this solution might not work for large distance travels like noclip because of onesync and entity culling.

Hello, could you share your code snippet with me? I tried using State bags for synchronization but didn’t see much difference :joy: