DrawMarker, help text e lib.showTextUI senza lag in FiveM
Disegna marcatori e mostra i prompt 'Press E' in FiveM senza un loop pesante: DrawMarker solo quando vicino, nativi di testo help, lib.showTextUI e punti ox_lib per le zone.
Disegni un marcatore, ti avvicini e sfarfalla, o non appare mai, o il tuo script rimane a 0.30 ms in resmon senza fare nulla. I marcatori e i prompt "Press E" sembrano semplici, ma sono la fonte classica di loop pesanti. Questo articolo mostra come disegnare un marcatore correttamente, come mostrare un prompt, e come smettere di pagare quando il giocatore è lontano.
DrawMarker deve essere eseguito ogni frame
Un marcatore viene disegnato per un frame ogni volta che chiami DrawMarker. Per mantenerlo sullo schermo lo chiami di nuovo ogni frame, in un loop con Wait(0):
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)Funziona, ma viene eseguito ogni frame per l'intera sessione, anche quando il giocatore è dall'altra parte della mappa. Correggilo dopo.
Disegna solo quando il giocatore è vicino
Misura la distanza e dormi più a lungo quando il giocatore è lontano. Solo lo stato vicino ha bisogno di Wait(0):
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)Lontano, il loop si sveglia una volta al secondo e fa una sottrazione. Vicino al marcatore viene eseguito per frame, solo mentre è necessario. Perché questo conta, e come leggerlo in resmon, è in resmon high ms: how to optimize.
Consiglio:
#(a - b)è la lunghezza di una differenza di vettore, la distanza. Ha bisogno di valorivec3, cheGetEntityCoordsrestituisce già.
Tipi di marcatore
Il primo argomento è il tipo di marcatore, un numero. Alcuni che i server usano molto:
| Tipo | Aspetto |
|---|---|
1 |
Un cilindro |
2 |
Una freccia chevron (ruotala di 180 gradi su X per farla puntare giù) |
23 |
Un anello piatto sul terreno |
25 |
Un anello piatto sul terreno, più sottile |
L'elenco completo dei tipi è nel sito della documentazione di FiveM, sotto i riferimenti di gioco, marcatori. Gli argomenti di scala cambiano la dimensione, e l'ultimo valore di colore è l'alfa (trasparenza). Posiziona un marcatore sul terreno a z - 1.0 così si siede sul pavimento, non fluttuando alla vita del giocatore.
Help text: il prompt integrato
Il gioco ha un messaggio di aiuto in alto a sinistra dello schermo. Definirai un'etichetta, quindi la visualizzerai ogni frame mentre il giocatore è in portata:
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~ viene sostituito dalla chiave che il giocatore usa per l'azione di contesto, che è E per impostazione predefinita. Chiama showHelp() all'interno del ramo distance < 1.5 sopra, quindi controlla la chiave:
if distance < 1.5 then
showHelp()
if IsControlJustReleased(0, 38) then
print('opened')
end
endRegistra l'etichetta una volta in cima al file, non all'interno del loop.
lib.showTextUI e lib.hideTextUI
Con ox_lib puoi mostrare un prompt stilizzato, e lo chiami una sola volta quando il giocatore entra, non ogni frame:
lib.showTextUI('[E] Open the garage', {
position = 'right-center',
icon = 'warehouse',
})
-- when the player leaves:
lib.hideTextUI()lib.isTextUIOpen() ti dice se uno è già sullo schermo. Ha bisogno di shared_script '@ox_lib/init.lua' nel tuo manifest (vedi the ox_lib menu guide). Il testo non è legato a una chiave: controlli comunque la chiave tu stesso, o usi un keybind.
Punti di ox_lib: nessun loop di distanza del tutto
Scrivere il loop di distanza a mano per ogni zona si accumula. lib.points lo fa per te: ox_lib controlla la distanza del giocatore a tutti i punti insieme, e esegue solo il tuo codice vicino a loro:
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
endCome funziona:
onEnterviene eseguito una volta quando il giocatore viene entro ladistance.onExitviene eseguito una volta quando lasciano.nearbyviene eseguito ogni frame mentre sono dentro ladistance, e per niente altrimenti. È dove vaDrawMarker.self.currentDistanceè la distanza corrente al punto.
Puoi creare centinaia di punti e solo quelli vicini al giocatore costano qualcosa. Rimuovi un punto che non ti serve più con point:remove().
Quale usare
- Una o due zone: il loop di distanza con un sleep va bene.
- Molte zone, o uno script che crea zone da config: usa
lib.points. - Interazioni su oggetti e ped: un target è meglio che un marcatore. Vedi ox_target: how to add targets.
Checklist
| Sintomo | Soluzione |
|---|---|
| Il marcatore sfarfalla o appare per un frame | Chiama DrawMarker ogni frame in un loop Wait(0) |
| Lo script costa tempo resmon quando inattivo | Dormi 500 a 1000 ms quando lontano, Wait(0) solo quando vicino |
| Il marcatore fluttua nell'aria | Disegnalo a z - 1.0 |
| Il testo del prompt non compare mai | Definiscilo con AddTextEntry, quindi visualizzalo ogni frame |
lib.showTextUI rimane sullo schermo |
Chiama lib.hideTextUI() all'uscita |
| Molte zone sono lente | Usa lib.points.new con onEnter, onExit e nearby |
Risposte rapide
Perché il mio marcatore scompare dopo un frame?
DrawMarker ha bisogno di essere chiamato ogni frame, in un loop con Wait(0). Chiamalo una volta e appare per un singolo frame.
Perché il mio script usa così tanto tempo resmon?
Un loop Wait(0) che misura la distanza ad ogni marcatore viene eseguito ogni frame tutto il tempo. Dormi più a lungo quando il giocatore è lontano, o usa i punti ox_lib così il loop viene eseguito solo vicino alla zona.
Quale è meglio, help text o lib.showTextUI?
Help text è integrato nel gioco e non ha bisogno di nessuna risorsa. lib.showTextUI è un prompt stilizzato da ox_lib ed è facile mostrare e nascondere dal codice. Scegli uno stile e mantienilo per l'intero server.
Script senza questo problema
Advanced BoostingBoosting di veicoli dal tablet: contratti dalla classe D alla S+, crew e coda in tempo reale.Vedi script →
Shop CreatorCrea un negozio in meno di un minuto — proprietari, dipendenti, casseforti e rapine inclusi.Vedi script →
Quest CreatorUn editor visuale di missioni e dialoghi con gli NPC, costruito nodo per nodo in gioco.Vedi script →