FiveM NUI React ve Vite ile: kurulum, geri çağırmalar ve tarayıcı geliştirmesi
FiveM NUI'yi React ve Vite ile oluşturun: ui_page ve fxmanifest dosyaları, base './', SendNUIMessage, RegisterNUICallback, SetNuiFocus ve tarayıcıda geliştirme.
Düz HTML küçük bir NUI için işe yarar, ancak gerçek bir arayüz React ile daha kolaydır. İnsanları tuzağa düşüren kısım React değil, tutkal: manifest, derleme çıktısı yolları ve iletilerin geri ve ileri nasıl gideceğidir.
Bu makale, FiveM'de yüklenen, her iki yönde Lua ile konuşan ve normal bir tarayıcı sekmesinde oluşturulabilen bir React ve Vite NUI'si ayarlar.
Proje düzeni
Arayüzü kaynağın içindeki web klasörüne koyun ve Vite ile oluşturun:
cd my_script
npm create vite@latest web -- --template react
cd web
npm installSonuç:
my_script/
fxmanifest.lua
client/main.lua
web/
package.json
vite.config.js
src/
dist/ (created by the build)vite.config: base './'
FiveM sayfanızı web sunucusu kökünden değil, nui:// adresinden yükler. Vite'nin varsayılan varlık yolları / ile başlar; bu daha sonra hiçbir yere işaret eder ve sizi boş bir sayfayla bırakır. Onları göreli yapın:
// web/vite.config.js
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
export default defineConfig({
plugins: [react()],
base: './',
build: { outDir: 'dist' },
})Ardından oluşturun:
npm run buildfxmanifest.lua
Yerleşik index.html öğesine ui_page işaret edin ve oyuncuyla tüm dist klasörünü files ile gönderin:
fx_version 'cerulean'
game 'gta5'
ui_page 'web/dist/index.html'
files {
'web/dist/index.html',
'web/dist/**',
}
client_script 'client/main.lua'files öğesinde listelenen dosyalar oyunculara gönderilir. Oyunda bir resim veya yazı tipi eksikse, dosya glob'u bunu içermedi. node_modules ve src öğesini listeden çıkartın: oyuncuların onlara ihtiyacı yok.
Lua'dan UI'ye: SendNUIMessage
İstemci komut dosyası bir ileti gönderir ve arayüze odak verir:
local open = false
local function setOpen(state)
open = state
SetNuiFocus(state, state)
SendNUIMessage({ action = 'setVisible', visible = state, data = { name = 'Mic' } })
end
RegisterCommand('myui', function()
setOpen(not open)
end, false)SetNuiFocus(hasFocus, hasCursor) klavye ve fareyi sayfaya verir. Her zaman geri verin, aksi halde imleç yapışır: NUI odak yapışmış imleç bölümüne bakın.
React'te ileti için dinleyin:
import { useEffect, useState } from 'react'
export default function App() {
const [visible, setVisible] = useState(false)
const [name, setName] = useState('')
useEffect(() => {
const onMessage = (event) => {
const { action, visible, data } = event.data
if (action === 'setVisible') {
setVisible(visible)
if (data) setName(data.name)
}
}
window.addEventListener('message', onMessage)
return () => window.removeEventListener('message', onMessage)
}, [])
if (!visible) return null
return <div className="panel">Hello {name}</div>
}Gizli olduğunda hiçbir şey işlemez bir sayfa, olağan modeldir; NUI sayfası kendisi yüklü kalır.
UI'den Lua'ya: fetch ve RegisterNUICallback
Diğer yön için, sayfa kaynağınızda URL'ye POST yapar. GetParentResourceName() FiveM'in sayfaya sağladığı ve kaynak adını döndüren bir işlevdir:
export async function nuiPost(eventName, data = {}) {
const resource = window.GetParentResourceName ? window.GetParentResourceName() : 'my_script'
const resp = await fetch(`https://${resource}/${eventName}`, {
method: 'POST',
headers: { 'Content-Type': 'application/json; charset=UTF-8' },
body: JSON.stringify(data),
})
return resp.json()
}<button onClick={() => nuiPost('close')}>Close</button>Lua'da, bunun ile ilgilenin. Geri çağırma çağrılması gerekir, aksi halde istek beklemede kalır:
RegisterNUICallback('close', function(data, cb)
setOpen(false) -- gives focus back
cb({ ok = true })
end)data kod çözülmüş JSON gövde ve cb getirmeyi yanıtlar. cb öğesine geçirilenler herhangi bir yanıt olarak geri gelir.
Tarayıcıda geliştirme
Her CSS değişikliği için yeniden oluşturmak ve kaynağı yeniden başlatmak yavaştır. Vite'ı çalıştırın ve normal bir tarayıcı sekmesinde çalışın:
npm run devOyun dışında, window.GetParentResourceName yok ve kimse size iletiler göndermez, bu nedenle her ikisini taklit edin:
export const isBrowser = !window.invokeNative
// in main.jsx, in dev only
if (isBrowser) {
setTimeout(() => {
window.postMessage({ action: 'setVisible', visible: true, data: { name: 'Mic' } }, '*')
}, 500)
}Yukarıdaki nuiPost işlevi zaten varsayılan bir kaynak adına geri döner. Tarayıcıda, istek basitçe başarısız olur, bu nedenle isBrowser doğru olduğunda bunu yakalayın veya çağrıyı atlayın. isBrowser doğru ise, çağrıyı atlayın. Sayfanın arkasındaki dünyayı oyun gösterir çünkü geliştirmede karanlık veya dama arkapalan kullanın.
Oyunun içinde yineleme
Oyunda son kontrolü yapmak için oluşturun ve yalnızca kaynağı yeniden başlatın:
npm run buildardından sunucu konsolunda ensure my_script yazın. vite build --watch ile, kaydettiğiniz her zaman dosyalar yeniden oluşturulur ve yalnızca kaynağı yeniden başlatırsınız.
Yaygın sorunlar
- Boş sayfa. Eksik
base: './', veyafilesweb/dist/**içermiyor. - Tıkladığında hiçbir şey olmaz.
RegisterNUICallbackadı getirme URL'si ile eşleşmiyor veyacbasla çağrılmıyor. - Kapatmadan sonra imleç yapışır. Kaynağın yeniden başlatılması da dahil olmak üzere her kapatma yolunda
SetNuiFocus(false, false)eksik. - Oyunda yazı tipleri ve resimler eksik. Mutlak yolla başvurulur veya
distiçinde değildir. - İleti hiç gelmez. Sayfa henüz yüklenmedi veya
actionadları Lua ve dinleyici arasında farklılık gösteriyor.
Kontrol listesi
| Belirti | Çözüm |
|---|---|
| Oyunda boş UI, tarayıcıda çalışır | vite.config base: './', ardından npm run build |
| Oyuncular için eksik dosyalar | fxmanifest.lua files { 'web/dist/**' } |
| Düğme hiçbir şey yapmıyor | RegisterNUICallback adını eşleştirin ve cb çağırın |
| Sayfadan oyuna ulaşılamaz | https://${GetParentResourceName()}/name öğesine fetch |
| İmleç geri gelmez | Kapatırken SetNuiFocus(false, false) |
| Oyun olmadan geliştirme | vite çalıştırın, postMessage ve GetParentResourceName taklit edin |
Kısa yanıtlar
React NUI'im neden FiveM'de boş sayfa?
Genellikle derleme mutlak varlık yollarını kullanır. vite.config öğesinde base: './' ayarlayın, yeniden derleyin ve fxmanifest.lua öğesindeki files tüm web/dist klasörünü içeriyor olup olmadığını kontrol edin.
UI verileri oyuna nasıl geri gönderir?
https://${GetParentResourceName()}/eventName öğesine fetch POST ile; Lua'da RegisterNUICallback('eventName', ...) ile işlenir; geri çağırmayı çağırması gerekir.
FiveM başlatmadan NUI'yi geliştirebilir miyim?
Evet. Tarayıcıda vite öğesini çalıştırın, oyunun dışında olduğunuzu algılayın ve Lua'nın gönderilecekleri taklit etmek için window.postMessage ile sahte iletiler gönderin.
Bu sorunu yaşatmayan scriptler
Mic PhoneTablete dönüşen katlanabilir bir telefon; oyuncunun gerçek telefonuna da taşınır.Scripti gör →
Clothing DesignerFiveM içinde kıyafet tasarlayın — fırça, katmanlar, görsel içe aktarma ve yapay zekâ — sonra giyin.Scripti gör →
Arcade MachinesGerçek kabinlerde oynanabilir yedi arcade oyunu; skor tabloları ve bahislerle.Scripti gör →