DrawMarker, tekst pomocy i lib.showTextUI bez opóźnienia w FiveM

Rysuj markery i pokaż 'Press E' prompty w FiveM bez ciężkiej pętli: DrawMarker tylko gdy blisko, rodzime tekst pomocy, lib.showTextUI i ox_lib punkty dla stref.

Rysujesz marker, podchodzisz do niego i migota, lub nigdy się nie pokazuje, lub twój skrypt siedzi na 0.30 ms w resmon robiąc nic. Markery i 'Press E' prompty wyglądają prosto, ale są klasycznym źródłem ciężkich pętli. Ten artykuł pokazuje, jak prawidłowo narysować marker, jak pokazać prompt, i jak przestać za to płacić, gdy gracz jest daleko.

DrawMarker musi działać każdą klatkę

Marker jest rysowany przez jedną klatkę każdy raz, gdy wołasz DrawMarker. Aby utrzymać go na ekranie wołasz go ponownie każdą klatkę, w pętli z Wait(0):

lua
local coords = vec3(441.2, -981.9, 30.7)

CreateThread(function()
    while true do
        DrawMarker(
            1,                                  -- type: cylinder
            coords.x, coords.y, coords.z - 1.0, -- position (on the ground)
            0.0, 0.0, 0.0,                      -- direction
            0.0, 0.0, 0.0,                      -- rotation
            1.5, 1.5, 0.5,                      -- scale
            50, 150, 255, 120,                  -- red, green, blue, alpha
            false, false, 2, false, nil, nil, false
        )
        Wait(0)
    end
end)

To działa, ale to działa każdą klatkę dla całej sesji, nawet gdy gracz jest po drugiej stronie mapy. Napraw to następne.

Rysuj tylko gdy gracz jest blisko

Mierz odległość i śpij dłużej, gdy gracz jest daleko. Tylko bliski stan potrzebuje Wait(0):

lua
local coords = vec3(441.2, -981.9, 30.7)

CreateThread(function()
    while true do
        local sleep = 1000
        local pedCoords = GetEntityCoords(PlayerPedId())
        local distance = #(pedCoords - coords)

        if distance < 15.0 then
            sleep = 0
            DrawMarker(1, coords.x, coords.y, coords.z - 1.0,
                0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.5, 1.5, 0.5,
                50, 150, 255, 120, false, false, 2, false, nil, nil, false)

            if distance < 1.5 then
                -- show the prompt here (next section)
            end
        end

        Wait(sleep)
    end
end)

Daleko, pętla budzi się raz na sekundę i robi jedno odejmowanie. Blisko markera działa per klatkę, tylko gdy musi. Dlaczego to liczy się i jak to przeczytać w resmon jest w resmon high ms: how to optimize.

Wskazówka: #(a - b) to długość różnicy wektora, odległość. Potrzebuje wartości vec3, które GetEntityCoords już zwraca.

Typy markerów

Pierwszy argument to typ markera, liczba. Kilka, które serwery używają wiele:

Typ Wygląda jak
1 Cylinder
2 Strzałka szewron (obróć ją o 180 stopni na X, aby wskazywała w dół)
23 Płaski pierścień na ziemi
25 Płaski pierścień na ziemi, cieńszy

Pełna lista typów jest na stronie dokumentacji FiveM, pod referencjami gry, markery. Argumenty skali zmieniają rozmiar, i ostatnia wartość koloru to alfa (przezroczystość). Umieść marker naziemny na z - 1.0, aby siedział na podłodze, nie unosił się na pasa gracza.

Tekst pomocy: wbudowany prompt

Gra ma wiadomość pomocy w lewym górnym rogu ekranu. Definiujesz etykietę, potem wyświetlasz ją każdą klatkę, gdy gracz jest w zasięgu:

lua
AddTextEntry('MY_SCRIPT_HELP', 'Press ~INPUT_CONTEXT~ to open the garage')

local function showHelp()
    BeginTextCommandDisplayHelp('MY_SCRIPT_HELP')
    EndTextCommandDisplayHelp(0, false, true, -1)
end

~INPUT_CONTEXT~ jest zastępowany kluczem, który gracz używa dla akcji kontekstowej, który jest E domyślnie. Wołaj showHelp() wewnątrz gałęzi distance < 1.5 powyżej, potem sprawdzić klucz:

lua
if distance < 1.5 then
    showHelp()
    if IsControlJustReleased(0, 38) then
        print('opened')
    end
end

Zarejestruj etykietę raz na górze pliku, nie wewnątrz pętli.

lib.showTextUI i lib.hideTextUI

Z ox_lib możesz pokazać stylizowany prompt i wołasz go raz gdy gracz wchodzi, nie każdą klatkę:

lua
lib.showTextUI('[E] Open the garage', {
    position = 'right-center',
    icon = 'warehouse',
})

-- when the player leaves:
lib.hideTextUI()

lib.isTextUIOpen() mówi ci, czy jeden jest już na ekranie. Potrzebuje shared_script '@ox_lib/init.lua' w manifeście (zobacz the ox_lib menu guide). Tekst nie jest powiązany z kluczem: wciąż sprawdzasz klucz samemu, lub używasz keybind.

ox_lib punkty: żadna pętla odległości w ogóle

Pisanie pętli odległości ręcznie dla każdej strefy się dodaje. lib.points to robi dla ciebie: ox_lib sprawdza odległość gracza do wszystkich punktów razem, i tylko uruchamia kod blisko nich:

lua
local point = lib.points.new({
    coords = vec3(441.2, -981.9, 30.7),
    distance = 15.0,
})

function point:onEnter()
    lib.showTextUI('[E] Open the garage')
end

function point:onExit()
    lib.hideTextUI()
end

function point:nearby()
    DrawMarker(1, self.coords.x, self.coords.y, self.coords.z - 1.0,
        0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.5, 1.5, 0.5,
        50, 150, 255, 120, false, false, 2, false, nil, nil, false)

    if self.currentDistance < 1.5 and IsControlJustReleased(0, 38) then
        print('opened')
    end
end

Jak to działa:

  • onEnter działa raz, gdy gracz wchodzi w distance.
  • onExit działa raz, gdy wychodź.
  • nearby działa każdą klatkę, gdy są wewnątrz distance, i wcale poza tym. To jest gdzie DrawMarker trafia.
  • self.currentDistance to bieżąca odległość do punktu.

Możesz tworzyć setki punktów i tylko te, które gracz jest blisko, kosztują cokolwiek. Usuń punkt, którego nie potrzebujesz już z point:remove().

Które używać

  • Jedna lub dwie strefy: pętla odległości z snem jest ok.
  • Wiele stref, lub skrypt, który tworzy strefy z config: użyj lib.points.
  • Interakcje na obiektach i pedach: cel jest lepszy niż marker. Zobacz ox_target: how to add targets.

Lista kontrolna

Symptom Naprawa
Marker migota lub pokazuje się przez jedną klatkę Wołaj DrawMarker każdą klatkę w Wait(0) pętli
Skrypt kosztuje czas resmon, gdy bezczynny Śpij 500 do 1000 ms, gdy daleko, Wait(0) tylko gdy blisko
Marker unosi się w powietrzu Rysuj go na z - 1.0
Tekst promptu nigdy się nie pokazuje Zdefiniuj go z AddTextEntry, potem wyświetlaj każdą klatkę
lib.showTextUI zostaje na ekranie Wołaj lib.hideTextUI() na wyjściu
Wiele stref jest wolne Użyj lib.points.new z onEnter, onExit i nearby

Szybkie odpowiedzi

Dlaczego mój marker znika po jednej klatce?

DrawMarker musi być wołany każdą klatkę, w pętli z Wait(0). Wołaj go raz i pokazuje się przez jedną klatkę.

Dlaczego mój skrypt używa tyle czasu resmon?

Pętla Wait(0), która mierzy odległość do każdego markera, działa każdą klatkę cały czas. Śpij dłużej, gdy gracz jest daleko, lub użyj ox_lib punktów, więc pętla działa tylko blisko strefy.

Które jest lepsze, tekst pomocy czy lib.showTextUI?

Tekst pomocy jest wbudowany w grę i nie potrzebuje zasobu. lib.showTextUI to stylizowany prompt z ox_lib i jest łatwy do pokazania i ukrycia z kodu. Wybierz jeden styl i trzymaj go dla całego serwera.

Skrypty bez tego problemu

Advanced BoostingBoosting pojazdów z tabletu: kontrakty od klasy D do S+, ekipy i kolejka na żywo.Zobacz skrypt →Shop CreatorZbuduj sklep w niecałą minutę — właściciele, pracownicy, sejfy i napady w zestawie.Zobacz skrypt →Quest CreatorWizualny edytor questów i dialogów z NPC, budowanych węzeł po węźle w grze.Zobacz skrypt →

Czytaj dalej