DrawMarker, help text e lib.showTextUI sem lag em FiveM
Desenhe markers e mostre prompts 'Press E' em FiveM sem um loop pesado: DrawMarker apenas quando próximo, nativos de help text, lib.showTextUI e pontos ox_lib para zonas.
Você desenha um marker, anda até ele e ele pisca, ou nunca mostra, ou seu script fica em 0.30 ms em resmon fazendo nada. Markers e prompts "Press E" parecem simples, mas são a fonte clássica de loops pesados. Este artigo mostra como desenhar um marker corretamente, como mostrar um prompt, e como parar de pagar por isso quando o jogador está longe.
DrawMarker tem que rodar cada frame
Um marker é desenhado por um frame cada vez que você chama DrawMarker. Para mantê-lo na tela você o chama novamente cada frame, em um loop com 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)Isso funciona, mas roda cada frame para a sessão inteira, mesmo quando o jogador está do outro lado do mapa. Corrija isso a seguir.
Desenhe apenas quando o jogador está próximo
Meça a distância e durma mais quando o jogador está longe. Apenas o estado próximo precisa 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)Longe, o loop acorda uma vez por segundo e faz uma subtração. Perto do marker roda por frame, apenas enquanto precisa. Por que isto importa, e como ler em resmon, está em resmon high ms: how to optimize.
Dica:
#(a - b)é o comprimento de uma diferença de vetor, a distância. Precisa de valoresvec3, queGetEntityCoordsjá retorna.
Tipos de marker
O primeiro argumento é o tipo de marker, um número. Alguns que servidores usam muito:
| Tipo | Parece |
|---|---|
1 |
Um cilindro |
2 |
Uma seta chevron (rotacione 180 graus em X para apontar para baixo) |
23 |
Um anel plano no chão |
25 |
Um anel plano no chão, mais fino |
A lista completa de tipos está no site de documentação do FiveM, em game references, markers. Os argumentos de escala mudam o tamanho, e o último valor de cor é o alpha (transparência). Coloque um marker de chão em z - 1.0 para que fique no chão, não flutuando na cintura do jogador.
Help text: o prompt integrado
O jogo tem uma mensagem de ajuda no topo esquerdo da tela. Você define um rótulo, depois a exibe cada frame enquanto o jogador está em alcance:
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~ é substituído pela chave que o jogador usa para a ação de contexto, que é E por padrão. Chame showHelp() dentro do branch distance < 1.5 acima, depois verifique a chave:
if distance < 1.5 then
showHelp()
if IsControlJustReleased(0, 38) then
print('opened')
end
endRegistre o rótulo uma vez no topo do arquivo, não dentro do loop.
lib.showTextUI e lib.hideTextUI
Com ox_lib você pode mostrar um prompt estilizado, e você o chama uma vez quando o jogador entra, não cada frame:
lib.showTextUI('[E] Open the garage', {
position = 'right-center',
icon = 'warehouse',
})
-- when the player leaves:
lib.hideTextUI()lib.isTextUIOpen() diz se um já está na tela. Precisa de shared_script '@ox_lib/init.lua' no seu manifesto (veja the ox_lib menu guide). O texto não é vinculado a uma chave: você ainda verifica a chave, ou usa um keybind.
ox_lib points: nenhum loop de distância em tudo
Escrever o loop de distância à mão para cada zona se acumula. lib.points faz para você: ox_lib verifica a distância do jogador para todos os pontos juntos, e apenas roda seu código perto deles:
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
endComo funciona:
onEnterroda uma vez quando o jogador vem dentro dedistance.onExitroda uma vez quando sai.nearbyroda cada frame enquanto eles estão dentro dedistance, e não em tudo caso contrário. É ondeDrawMarkervai.self.currentDistanceé a distância atual para o ponto.
Você pode criar centenas de pontos e apenas os que o jogador está perto custam qualquer coisa. Remova um ponto que você não precisa mais com point:remove().
Qual usar
- Uma ou duas zonas: o loop de distância com um sleep é bem.
- Muitas zonas, ou um script que cria zonas de config: use
lib.points. - Interações em objetos e peds: um target é melhor que um marker. Veja ox_target: how to add targets.
Checklist
| Sintoma | Solução |
|---|---|
| Marker pisca ou mostra por um frame | Chame DrawMarker cada frame em um loop Wait(0) |
| Script custa tempo de resmon quando ocioso | Durma 500 a 1000 ms quando longe, Wait(0) apenas quando perto |
| Marker flutua no ar | Desenhe em z - 1.0 |
| Texto de prompt nunca mostra | Defina com AddTextEntry, depois exiba cada frame |
lib.showTextUI fica na tela |
Chame lib.hideTextUI() ao sair |
| Muitas zonas são lentas | Use lib.points.new com onEnter, onExit e nearby |
Respostas rápidas
Por que meu marker desaparece após um frame?
DrawMarker tem que ser chamado a cada frame, em um loop com Wait(0). Chame uma vez e ele mostra por um único frame.
Por que meu script usa tanto tempo de resmon?
Um loop Wait(0) que mede distância para cada marker roda cada frame o tempo todo. Durma mais quando o jogador está longe, ou use pontos ox_lib para que o loop apenas rode perto da zona.
Qual é melhor, help text ou lib.showTextUI?
Help text é integrado ao jogo e não precisa de recurso. lib.showTextUI é um prompt estilizado de ox_lib e é fácil de mostrar e esconder do código. Escolha um estilo e mantenha para seu servidor inteiro.
Scripts sem esse problema
Advanced BoostingBoosting de veículos pelo tablet: contratos da classe D à S+, crews e fila ao vivo.Ver script →
Shop CreatorMonte uma loja em menos de um minuto — donos, funcionários, cofres e assaltos inclusos.Ver script →
Quest CreatorUm editor visual de missões e diálogos com NPCs, montado nó por nó dentro do jogo.Ver script →