DrawMarker, texto de ayuda y lib.showTextUI sin lag en FiveM
Dibuja marcadores y muestra indicadores «Presiona E» en FiveM sin un bucle pesado: DrawMarker solo cuando esté cerca, natives de texto de ayuda, lib.showTextUI y puntos ox_lib para zonas.
Dibujas un marcador, te acercas a él y parpadea, o nunca se muestra, o tu script se queda en 0.30 ms en resmon sin hacer nada. Los marcadores e indicadores «Presiona E» se ven simples, pero son la fuente clásica de bucles pesados. Este artículo te muestra cómo dibujar un marcador correctamente, cómo mostrar un indicador, y cómo dejar de pagar por ello cuando el jugador está lejos.
DrawMarker tiene que ejecutarse cada fotograma
Un marcador se dibuja durante un fotograma cada vez que llamas a DrawMarker. Para mantenerlo en pantalla lo llamas de nuevo cada fotograma, en un bucle 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)Eso funciona, pero se ejecuta cada fotograma durante toda la sesión, incluso cuando el jugador está al otro lado del mapa. Arregla eso a continuación.
Solo dibuja cuando el jugador está cerca
Mide la distancia y duerme más cuando el jugador está lejos. Solo el estado cercano necesita 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)Lejos, el bucle se despierta una vez por segundo y hace una resta. Cerca del marcador se ejecuta por fotograma, solo mientras lo necesita. Por qué esto importa, y cómo leerlo en resmon, está en resmon high ms: how to optimize.
Consejo:
#(a - b)es la longitud de una diferencia de vector, la distancia. Necesita valoresvec3, queGetEntityCoordsya devuelve.
Tipos de marcadores
El primer argumento es el tipo de marcador, un número. Unos pocos que los servidores usan mucho:
| Tipo | Se ve como |
|---|---|
1 |
Un cilindro |
2 |
Una flecha de comilla (rótala 180 grados en X para que apunte hacia abajo) |
23 |
Un anillo plano en el suelo |
25 |
Un anillo plano en el suelo, más delgado |
La lista completa de tipos está en el sitio de documentación de FiveM, bajo referencias de juego, marcadores. Los argumentos de escala cambian el tamaño, y el último valor de color es el alfa (transparencia). Coloca un marcador de suelo en z - 1.0 para que se asiente en el piso, no flotando en la cintura del jugador.
Texto de ayuda: el indicador integrado
El juego tiene un mensaje de ayuda en la parte superior izquierda de la pantalla. Defines una etiqueta, luego la muestras cada fotograma mientras el jugador esté en rango:
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~ se reemplaza con la tecla que el jugador usa para la acción de contexto, que es E por defecto. Llama a showHelp() dentro de la rama distance < 1.5 anterior, luego comprueba la tecla:
if distance < 1.5 then
showHelp()
if IsControlJustReleased(0, 38) then
print('opened')
end
endRegistra la etiqueta una vez en la parte superior del fichero, no dentro del bucle.
lib.showTextUI y lib.hideTextUI
Con ox_lib puedes mostrar un indicador con estilo, y lo llamas una vez cuando el jugador entra, no cada fotograma:
lib.showTextUI('[E] Open the garage', {
position = 'right-center',
icon = 'warehouse',
})
-- when the player leaves:
lib.hideTextUI()lib.isTextUIOpen() te dice si ya hay uno en pantalla. Necesita shared_script '@ox_lib/init.lua' en tu manifest (ver the ox_lib menu guide). El texto no está vinculado a una tecla: aún compruebas la tecla tú mismo, u usa un keybind.
Puntos ox_lib: ningún bucle de distancia en absoluto
Escribir el bucle de distancia a mano para cada zona suma. lib.points lo hace por ti: ox_lib comprueba la distancia del jugador a todos los puntos juntos, y solo ejecuta tu código cerca de ellos:
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
endCómo funciona:
onEnterse ejecuta una vez cuando el jugador entra dentro dedistance.onExitse ejecuta una vez cuando se va.nearbyse ejecuta cada fotograma mientras estén dentro dedistance, y no en absoluto si no. Ahí es donde vaDrawMarker.self.currentDistancees la distancia actual al punto.
Puedes crear cientos de puntos y solo los cerca del jugador cuestan algo. Elimina un punto que ya no necesites con point:remove().
Cuál usar
- Una o dos zonas: el bucle de distancia con un sleep está bien.
- Muchas zonas, o un script que crea zonas desde configuración: usa
lib.points. - Interacciones en objetos y peds: un objetivo es mejor que un marcador. Ver ox_target: how to add targets.
Lista de verificación
| Síntoma | Solución |
|---|---|
| El marcador parpadea o se muestra por un fotograma | Llama a DrawMarker cada fotograma en un bucle Wait(0) |
| El script cuesta tiempo de resmon cuando está inactivo | Duerme 500 a 1000 ms cuando está lejos, Wait(0) solo cuando esté cerca |
| El marcador flota en el aire | Dibújalo en z - 1.0 |
| El texto del indicador nunca se muestra | Defínelo con AddTextEntry, luego muéstralo cada fotograma |
lib.showTextUI permanece en pantalla |
Llama a lib.hideTextUI() al salir |
| Muchas zonas son lentas | Usa lib.points.new con onEnter, onExit y nearby |
Respuestas rápidas
¿Por qué mi marcador desaparece después de un fotograma?
DrawMarker tiene que llamarse cada fotograma, en un bucle con Wait(0). Lláma lo una vez y se muestra por un fotograma.
¿Por qué mi script usa tanto tiempo de resmon?
Un bucle Wait(0) que mide la distancia a cada marcador se ejecuta cada fotograma todo el tiempo. Duerme más cuando el jugador está lejos, o usa puntos ox_lib para que el bucle solo se ejecute cerca de la zona.
¿Cuál es mejor, texto de ayuda o lib.showTextUI?
El texto de ayuda está integrado en el juego y no necesita ningún recurso. lib.showTextUI es un indicador con estilo de ox_lib y es fácil de mostrar y ocultar desde el código. Elige un estilo y mantenlo para todo tu servidor.
Scripts que evitan este problema
Advanced BoostingBoosting de vehículos desde una tablet: contratos de clase D a S+, crews y cola en vivo.Ver script →
Shop CreatorCrea una tienda en menos de un minuto — dueños, empleados, caja fuerte y atracos.Ver script →
Quest CreatorUn editor visual de misiones y diálogos con NPC, nodo a nodo dentro del juego.Ver script →