FiveM NUI คืออะไร วิธีสร้าง UI ด้วย HTML CSS JavaScript แบบละเอียด
FiveM NUI คือระบบ User Interface แบบ HTML ของ CitizenFX/FiveM ที่ช่วยให้ผู้พัฒนาสร้างหน้าต่างและ Interface ภายในเกมด้วยเทคโนโลยีเว็บ เช่น HTML, CSS และ JavaScript แทนการจำกัดอยู่เฉพาะ HUD หรือ UI ดั้งเดิมของ GTA V โดย Cfx.re ระบุว่า NUI ย่อมาจาก New UI และปัจจุบันทำงานผ่าน Chromium Embedded Framework พร้อมรองรับ Web Frameworks อย่าง React หรือ Angular และ WebGL ได้ด้วย.
NUI ถูกนำไปใช้กับระบบจำนวนมาก เช่น
HUDInventoryPhoneBankingGarageCharacter MenuJob MenuVehicle MenuScoreboardSettingsShopAdmin MenuLoading Screen
บทความนี้จาก comsiam จะอธิบายตั้งแต่โครงสร้าง NUI, fxmanifest.lua, ui_page, SendNUIMessage, NUI Callback, SET_NUI_FOCUS, JavaScript Message, DUI ไปจนถึง Security และแนวทาง Optimize NUI สำหรับ Server จริง
① FiveM NUI คืออะไร
NUI คือระบบสร้าง User Interface ภายใน FiveM ด้วย Web Technologies
โครงสร้างพื้นฐานคือ
FiveM Script↓NUI↓HTMLCSSJavaScript↓Interface บนหน้าจอ
Cfx.re อธิบายว่า NUI เป็น HTML-based UI Functionality ของ CitizenFX Framework และ Fullscreen NUI สามารถ Overlay อยู่เหนือ Game View ได้.
② NUI ย่อมาจากอะไร
NUI ย่อมาจาก
New UI
ตาม Documentation ของ Cfx.re.
อย่างไรก็ตามในงาน FiveM ปัจจุบันคำว่า NUI มักถูกใช้หมายถึงระบบ HTML-based UI ทั้งชุด
③ NUI ใช้อะไรสร้าง
พื้นฐานคือ
HTMLCSSJavaScript
และ Cfx.re ระบุว่าสามารถใช้ Framework หรือ Technology ฝั่งเว็บเพิ่มเติมได้ เช่น React, Angular และ accelerated WebGL.
④ HTML ทำหน้าที่อะไร
HTML เป็นโครงสร้างของ Interface
ตัวอย่าง
<div id="inventory"><h1>Inventory</h1><div id="items"></div></div>
เปรียบเสมือนโครงกระดูกของ UI
⑤ CSS ทำหน้าที่อะไร
CSS ใช้ควบคุม
ตำแหน่งขนาดสีFontAnimationResponsive LayoutOpacityTransition
ตัวอย่าง
#inventory {position: absolute;width: 600px;height: 700px;top: 50%;left: 50%;transform:translate(-50%, -50%);}
เพราะ NUI เป็น Web UI จึงสามารถใช้ CSS Layout Techniques แบบเว็บได้.
⑥ JavaScript ทำหน้าที่อะไร
JavaScript ใช้ควบคุม Logic ฝั่ง Interface เช่น
เปิด Menuปิด Menuอัปเดตข้อมูลกด Buttonลาก Itemค้นหาจัดการ Stateส่ง Callback กลับเกม
และสามารถรับ Message จาก FiveM Script ผ่าน Browser message Event ได้.
⑦ NUI ใช้ทำ HUD ได้ไหม
ได้
เช่น
HealthArmorHungerThirstMoneyJobVoiceSpeedometer
Fullscreen NUI ถูกวาง Overlay เหนือ Game View จึงเหมาะกับ HUD และ Interface ที่แสดงบนหน้าจอ.
⑧ NUI ใช้ทำ Inventory ได้ไหม
ได้
Inventory สามารถมี
Item SlotsImagesDrag & DropAmountWeightSearchContext Menu
และใช้ NUI Callback ส่ง Action กลับเข้าสู่ Game Script เมื่อผู้เล่นกดหรือใช้งาน Item.
⑨ NUI ใช้ทำ Phone ได้ไหม
ได้
Phone Resource สามารถสร้าง UI คล้าย Mobile Application ด้วย HTML/CSS/JavaScript แล้วเชื่อมข้อมูลกับ Client/Server Scripts
ตัว NUI เป็น Presentation Layer ส่วนข้อมูลหรือ Gameplay Authority ควรถูกควบคุมจาก Script/Server ตาม Architecture ของ Resource
⑩ NUI ต่างจาก HUD อย่างไร
จำง่าย ๆ
NUI= เทคโนโลยี UIHUD= หนึ่งในสิ่งที่สร้างด้วย NUI
ตัวอย่าง
NUI├── HUD├── Inventory├── Phone├── Garage└── Banking
NUI จึงกว้างกว่า HUD.
⑪ NUI ต่างจาก Loading Screen อย่างไร
Loading Screen เป็น NUI Frame ชนิดพิเศษที่ FiveM เรียกว่า
loadingScreen
และกำหนดด้วย loadscreen ใน Resource Manifest แทน ui_page.
ดังนั้น
Gameplay UI→ ui_pageLoading Screen→ loadscreen
⑫ NUI ต่างจาก DUI อย่างไร
Fullscreen NUI
UI Overlay บนหน้าจอ
ส่วน DUI — Direct-rendered UI
NUI ที่ Render ไปยัง Runtime Texture
Cfx.re ระบุว่า DUI สามารถนำไปใช้กับ Cinema Screen, Render Target หรือ UI ใน World Space ได้.
⑬ ตัวอย่าง NUI กับ DUI
Inventory Menu→ NUIHUD→ NUIPhone Fullscreen UI→ NUITV Screen ในโลกเกม→ DUICinema Screen→ DUI
DUI มี APIs เช่น CREATE_DUI, GET_DUI_HANDLE, SEND_DUI_MESSAGE และ DESTROY_DUI.
⑭ NUI ต่างจาก Scaleform อย่างไร
Scaleform เป็น GUI Technology ดั้งเดิมที่ GTA V ใช้ ซึ่ง Cfx.re ระบุว่าอิง Flash/ActionScript 2
ส่วน NUI ใช้ Web Technologies อย่าง HTML/CSS/JavaScript.
สำหรับ Custom UI สมัยใหม่ NUI มักเข้าใจและพัฒนาได้สะดวกสำหรับคนที่มีพื้นฐาน Web Development
⑮ Resource NUI ต้องมี fxmanifest.lua หรือไม่
ต้องมี Resource Manifest
Cfx.re ระบุว่า FiveM Resource ทุกตัวต้องมี fxmanifest.lua เพื่อกำหนด Files/Scripts ที่ Resource ใช้งาน.
ตัวอย่าง
my_nui/├── fxmanifest.lua├── client.lua└── html/├── index.html├── style.css└── app.js
⑯ ui_page คืออะไร
ui_page ใช้กำหนดหน้า NUI ของ Resource
ตัวอย่าง
ui_page 'html/index.html'
Cfx.re ระบุว่า ui_page สามารถชี้ไปยัง Local File หรือ URL และถ้าใช้ Local File ตัว File และ Dependencies ต้องถูกประกาศใน files.
⑰ ตัวอย่าง fxmanifest.lua สำหรับ NUI
fx_version 'cerulean'game 'gta5'client_script 'client.lua'ui_page 'html/index.html'files {'html/index.html','html/style.css','html/app.js'}
โครงสร้างนี้ใช้ ui_page และ files ตาม Resource Manifest ของ FiveM.
⑱ ทำไมต้องใส่ files
ถ้า
index.html
ต้องใช้
style.cssapp.jsimagesfonts
Files เหล่านี้ต้องถูก Resource จัดให้ Client ใช้งานตาม Manifest
Cfx.re ระบุว่า Local ui_page และ Dependencies ต้องถูกอ้างใน files.
⑲ NUI Resource ขั้นต่ำต้องมีอะไร
อย่างง่าย
fxmanifest.luaclient.luahtml/index.htmlhtml/style.csshtml/app.js
ไม่จำเป็นต้องใช้ React หรือ Framework ขนาดใหญ่หาก Interface ไม่ซับซ้อน
⑳ Flow การทำงานของ NUI
โครงสร้างที่ควรจำคือ
GAME DATA↓CLIENT SCRIPT↓SendNUIMessage↓NUI JavaScript↓DOM↓PLAYER
เมื่อผู้เล่นกด UI
PLAYER↓NUI JavaScript↓NUI Callback↓CLIENT SCRIPT↓SERVER ถ้าจำเป็น
Fullscreen NUI รองรับการส่ง Message จาก Game Script ไปยัง Browser UI และ NUI Callback ใช้ส่งข้อมูลกลับเข้าสู่ Game Script.
㉑ SendNUIMessage คืออะไร
Lua มี Function
SendNUIMessage({action = 'open'})
สำหรับส่ง Table Data เข้า NUI
Cfx.re ระบุว่า Lua Wrapper จะ Encode Data เป็น JSON ก่อนส่งเข้าสู่ NUI Page ของ Resource.
㉒ ตัวอย่างเปิด NUI
Client Lua
RegisterCommand('openmenu', function()SendNUIMessage({action = 'open'})end)
JavaScript
window.addEventListener('message',function(event) {if (event.data.action === 'open') {document.body.classList.add('open');}});
Browser-side message Event เป็น Pattern ที่ Cfx.re ใช้ใน Fullscreen NUI Documentation.
㉓ ส่งข้อมูลหลายค่าได้ไหม
ได้
ตัวอย่าง
SendNUIMessage({action = 'playerData',health = 100,armor = 50,job = 'police'})
Lua Wrapper สามารถรับ Table แล้ว Encode เพื่อส่งเป็น Message ให้ NUI.
㉔ JavaScript รับข้อมูลอย่างไร
ตัวอย่าง
window.addEventListener('message',(event) => {const data = event.data;if (data.action === 'playerData') {console.log(data.health);console.log(data.armor);console.log(data.job);}});
นี่คือทิศทาง
FiveM→ NUI
ผ่าน NUI Message.
㉕ NUI ส่งข้อมูลกลับ FiveM ได้หรือไม่
ได้
ใช้ NUI Callback
Cfx.re ระบุว่า NUI Callback เป็นวิธีส่งข้อมูลระหว่าง User Interface กับ Game และข้อมูลที่ส่งหรือรับต้องสามารถ Encode เป็น JSON ได้.
㉖ NUI Callback ใช้กับอะไร
ตัวอย่าง
ซื้อ Itemใช้ ItemSave Settingsปิด Menuเลือก Characterฝากเงินถอนเงินเลือกรถ
แต่ Action สำคัญต้องผ่าน Validation ที่เหมาะสมก่อนเปลี่ยน Gameplay State
㉗ ตัวอย่าง NUI Callback ฝั่ง Lua
RegisterNUICallback('close',function(data, cb)SetNuiFocus(false,false)cb({ok = true})end)
NUI Callback Documentation ระบุว่า Callback ควร Return Data ผ่าน cb.
㉘ ทำไมต้องตอบ cb
Cfx.re ระบุว่า หาก NUI Callback ไม่ Return ข้อมูลผ่าน cb Request สามารถ Timeout และ Error จะย้อนกลับไปยัง fetch ที่เรียกจาก UI.
ดังนั้นควรตอบอย่างน้อย
cb({ok = true})
㉙ ฝั่ง JavaScript เรียก Callback อย่างไร
แนวคิดคือ UI ส่ง Request กลับไปยัง NUI Callback Endpoint ของ Resource
ข้อมูลต้องเป็น JSON-compatible ตามข้อกำหนดของ NUI Callback.
โครงสร้างโดยรวมคือ
Button Click↓JavaScript Request↓NUI Callback↓Lua↓cb(...)↓JavaScript ได้ Response
㉚ NUI Focus คืออะไร
Fullscreen NUI อาจมีหรือไม่มี Input Focus
FiveM มี
SET_NUI_FOCUS
สำหรับกำหนด Keyboard Focus และ Mouse Cursor Focus ของ NUI Resource.
㉛ เปิด NUI Focus อย่างไร
ตัวอย่าง
SetNuiFocus(true,true)
แนวคิดคือ
hasFocus = truehasCursor = true
ทำให้ UI สามารถรับ Keyboard/Mouse ตาม Focus State ที่กำหนด.
㉜ ปิด NUI Focus อย่างไร
SetNuiFocus(false,false)
เมื่อปิด Menu ควรคืน Input ให้ Gameplay
นี่ช่วยป้องกันปัญหา
เมาส์ค้างเดินไม่ได้กดเกมไม่ได้
㉝ ตรวจว่า NUI มี Focus อยู่ไหม
FiveM มี
IS_NUI_FOCUSED
ซึ่งคืน Current NUI Focus State ที่เคยถูกตั้งผ่าน SET_NUI_FOCUS.
มีประโยชน์มากเวลา Debug Mouse ค้าง
㉞ HUD ต้องใช้ Focus ไหม
ถ้า HUD มีหน้าที่เพียงแสดง
HealthArmorMoneySpeed
ไม่จำเป็นต้องรับ Mouse/Keyboard Focus
ควรใช้ Focus เฉพาะ UI ที่ต้อง Interaction
㉟ Inventory ต้องใช้ Focus ไหม
โดยทั่วไป Inventory ที่ผู้เล่นต้อง
คลิกลากกด Button
ต้องมี Input Flow ที่เหมาะสม ซึ่งมักเกี่ยวข้องกับ NUI Focus
เมื่อปิด Inventory ต้องคืน Focus ให้ Game
㊱ NUI หลาย Resource แย่ง Focus กันได้ไหม
Cfx.re ระบุว่า NUI มี Focus Stack แบบจำกัด Resource ที่ถูก Focus ล่าสุดจะอยู่ด้านบน และ Fullscreen NUI Resources ทำงานเป็น Fullscreen iframes โดยไม่มี Click-through ระหว่าง Resources.
ดังนั้น Resource เช่น
PhoneInventoryHUD SettingsBank
ควรมี Lifecycle เปิด–ปิดชัดเจน
㊲ ทำไมเปิด Phone แล้ว Inventory คลิกไม่ได้
หนึ่งในสิ่งที่ควรตรวจคือ NUI Focus Stack
ถ้า Phone ได้ Focus หลัง Inventory
Phone อาจเป็น Resource ที่อยู่บน Focus Stack ล่าสุดตาม Behavior ที่ Cfx.re อธิบาย.
㊳ NUI Focus กับ Z-index เหมือนกันไหม
ไม่ควรถือว่าเป็นเรื่องเดียวกัน
CSS z-index จัดลำดับ Elements ภายในหน้า Web เดียว
ส่วน NUI Focus Stack เกี่ยวกับ Resource NUI และ Input/Ordering ระหว่าง Resources ตามกลไก FiveM.
㊴ NUI เปิดแต่เมาส์ไม่ขึ้น
ตรวจ
SetNuiFocus(true, true)
และตรวจว่า Resource อื่นไม่ได้เปลี่ยน Focus หลังจากนั้น.
㊵ NUI ปิดแล้วเมาส์ยังค้าง
ตรวจ Close Flow
ต้องมี
SetNuiFocus(false,false)
หาก Resource ถูก Restart/Stop ขณะ Menu เปิด ก็ควรมี Cleanup ที่เหมาะสมด้วย
㊶ NUI เปิดไม่ขึ้นต้องตรวจอะไร
ตรวจตาม Layer
Resource↓fxmanifest.lua↓ui_page↓files↓HTML↓CSS↓JavaScript↓SendNUIMessage
ui_page และ Dependencies ของ Local UI ต้องถูกประกาศตาม Resource Manifest.
㊷ วิธี Test NUI ที่ง่ายที่สุด
ทำ HTML
<h1>NUI TEST</h1>
ถ้า UI Test แสดงได้
แสดงว่า
Resourceui_pageHTML
ทำงานแล้ว
จากนั้นค่อยเพิ่ม JavaScript และ Data Integration
㊸ HTML ขึ้นแต่ข้อมูลไม่มา
ตอนนี้ให้ตรวจ
SendNUIMessageMessage ActionJavaScript Listener
Cfx.re รองรับ Message Flow จาก Script ไป Browser ผ่าน SEND_NUI_MESSAGE/SendNUIMessage.
㊹ Message เข้าแต่ UI ไม่เปลี่ยน
ถ้า
console.log(event.data);
เห็นข้อมูลแล้ว
ปัญหาน่าจะอยู่
JavaScript LogicDOM SelectorCSSState
ไม่ใช่ FiveM Message Layer
㊺ Action Name ต้องตรงกัน
Client
SendNUIMessage({action = 'openInventory'})
JavaScript
if (event.data.action=== 'openInventory') {// ...}
ถ้าเขียน
openinventory
อีกฝั่งหนึ่ง Logic ก็จะไม่ตรงกัน
㊻ NUI DevTools คืออะไร
FiveM เปิด Chromium Developer Tools สำหรับ NUI และสามารถเรียกจาก F8 ด้วย
nui_devtools
ตาม Client Console Documentation.
เอกสาร Fullscreen NUI ยังระบุว่า CEF Remote Debugging Tools สามารถใช้ตรวจ NUI ขณะเกมทำงานได้.
㊼ NUI DevTools ดูอะไรได้
เช่น
ConsoleElementsDOMCSSJavaScript ErrorsNetwork
นี่คือเครื่องมือสำคัญที่สุดเมื่อ
HTML ขึ้นแต่ UI ทำงานผิด
㊽ F8 ต่างจาก NUI DevTools อย่างไร
จำง่าย ๆ
F8→ FiveM Client / Script ErrorsNUI DevTools→ HTML / CSS / JavaScript
ทั้งสองควรใช้ร่วมกันในการ Debug Resource ที่มี NUI.
㊾ NUI ทำ FPS ตกได้ไหม
มีโอกาสจาก Architecture และ Rendering Work
เช่น
ส่ง Message ถี่เกินJavaScript ทำงานมากDOM Update จำนวนมากAnimation/Effects จำนวนมาก
ขณะเดียวกัน Client Script ของ Resource ก็อาจเป็นต้นเหตุได้
FiveM มี resmon สำหรับดู CPU/Memory Usage ของแต่ละ Resource.
㊿ ใช้ resmon ตรวจ NUI ได้อย่างไร
เปิด
resmon true
Resource Monitor จะแสดง CPU และ Memory Usage ของ Resources และ Cfx.re ระบุว่าเหมาะสำหรับตรวจ Performance Problems ระหว่าง Gameplay.
ถ้า NUI Resource ใช้ Client CPU สูง ควรตรวจ Client Loop เพิ่ม
51. อย่าส่ง NUI Message ทุกอย่างทุก Frame
ตัวอย่างที่ควรระวัง
while true doWait(0)SendNUIMessage({money = money,job = job,name = name,health = health})end
แม้
moneyjobname
ไม่ได้เปลี่ยน
ควรออกแบบ Data Updates ตามความถี่ของข้อมูล และใช้ Events/Change Detection เมื่อเหมาะสม
52. ส่งเฉพาะค่าที่เปลี่ยน
ตัวอย่าง
local lastMoney = nillocal function updateMoney(money)if money == lastMoney thenreturnendlastMoney = moneySendNUIMessage({action = 'money',value = money})end
SendNUIMessage เป็น Transport จาก Script ไป NUI ดังนั้นการไม่ส่งค่าซ้ำที่ไม่มีผลต่อ UI เป็น Optimization เชิง Architecture ที่ดี.
53. JavaScript ก็ไม่ควร Render ค่าเดิมซ้ำ
ตัวอย่าง
if (lastMoney !== data.value) {lastMoney = data.value;moneyElement.textContent =data.value;}
ทำให้ Update เฉพาะเมื่อ Visual State เปลี่ยน
54. อย่า Render HTML ทั้งหน้าใหม่ทุก Message
ถ้าความเร็วเปลี่ยนเพียงหนึ่งค่า
ไม่จำเป็นต้อง Rebuild
HUD ทั้งหน้า
ใหม่
ควร Update เฉพาะ Element ที่เปลี่ยน
55. React ใช้กับ NUI ได้ไหม
ได้
Cfx.re ระบุว่า NUI รองรับ Web Frameworks อย่าง React และ Angular.
แต่ React ไม่ได้ทำให้ Resource เร็วหรือช้าโดยอัตโนมัติ
Performance ยังขึ้นกับ State Architecture และ Render Frequency
56. Vanilla JavaScript ใช้ได้ไหม
ได้
NUI ไม่บังคับให้ใช้ Framework
Resource เล็ก เช่น
SpeedometerSimple HUDPopupConfirmation Menu
สามารถใช้ HTML/CSS/JavaScript ปกติได้
57. NUI Callback ปลอดภัยหรือไม่
NUI Callback เป็นช่องทางรับข้อมูลจาก UI กลับเข้าสู่ Game Script แต่ข้อมูลจาก Client/UI ไม่ควรถูกถือว่าเชื่อถือได้สำหรับการทำ Action สำคัญโดยอัตโนมัติ
Cfx.re Security Guide เตือนว่าฝั่ง Client สามารถ Trigger Events ได้ใน Context ต่าง ๆ และ Server ควรตรวจข้อมูล/เงื่อนไขที่สำคัญเอง.
58. อย่าให้ NUI เป็นคนอนุมัติเงิน
ตัวอย่างที่ไม่ควรออกแบบ
NUI ส่งmoney = 1000000↓Server เชื่อทันที↓เพิ่มเงิน
UI ควรส่งเพียง Intent เช่น
withdraw 1000
แล้ว Server ตรวจ
ยอดเงินจริงPermissionTransaction Stateข้อจำกัด
ก่อนดำเนินการ
แนวคิดนี้สอดคล้องกับ Cfx.re Security Guidance ที่ให้ Validate Logic สำคัญฝั่ง Server.
59. Inventory Item ก็เช่นกัน
ไม่ควรให้ NUI บอกว่า
ฉันมี Item 100 ชิ้น
แล้ว Server เชื่อ
Server ควรเป็น Source of Truth สำหรับข้อมูล Gameplay สำคัญ เช่น Inventory, Money และ Permission
60. NUI Callback Data ต้องเป็นอะไร
Cfx.re ระบุว่าข้อมูลที่ส่งและรับผ่าน NUI Callback ต้องสามารถ JSON Encode ได้.
ดังนั้น Structure ควรเป็นข้อมูลพื้นฐาน เช่น
stringnumberbooleanarrayobject/table ที่ Encode ได้
61. NUI Resource ควรแยก Data กับ Presentation
Architecture ที่ดูแลง่ายคือ
SERVER↓CLIENT DATA ADAPTER↓NUI STATE↓RENDER
ไม่ควรให้ HTML/JavaScript เป็นเจ้าของ Gameplay Authority
62. ตัวอย่าง Architecture Inventory
Database / Server Inventory↓Server↓Client↓SendNUIMessage↓Inventory UI
เมื่อผู้เล่นกด Use Item
Inventory UI↓NUI Callback↓Client↓Server Validation↓Action
ทำให้ Presentation กับ Gameplay Logic แยกออกจากกัน
63. NUI รองรับหลาย Resolution หรือไม่
เพราะเป็น Web UI จึงสามารถออกแบบ Responsive ด้วย CSS ได้
ควรทดสอบ
1920×10802560×14404K21:9Ultrawide
และหลีกเลี่ยง Hard-code ตำแหน่งเฉพาะ Resolution เดียว
64. ตัวอย่าง Responsive Layout
.menu {width: min(90vw,800px);max-height: 85vh;}
ช่วยให้ UI ปรับตาม Viewport ได้ง่ายกว่าใช้ขนาด Pixel ตายตัวทั้งหมด
65. NUI ใช้ภาพและ Font ได้ไหม
ได้ในฐานะ Web Assets
แต่ถ้าเป็น Local Files ของ Resource ต้องประกาศให้ Resource จัดส่ง Files ที่ Dependencies ต้องใช้ตาม files ใน Manifest.
66. External URL เป็น ui_page ได้ไหม
ได้
Cfx.re Resource Manifest ระบุว่า ui_page รองรับทั้ง Local File และ Absolute URL.
อย่างไรก็ตาม External UI เพิ่ม Dependency ต่อ Host/Network ภายนอก จึงควรเลือกตาม Infrastructure และ Availability ที่ต้องการ
67. NUI กับ DUI ใช้ Message ต่างกันหรือไม่
Fullscreen NUI ใช้
SEND_NUI_MESSAGE
ส่วน DUI มี
SEND_DUI_MESSAGE
สำหรับส่ง JSON Message ไปยัง DUI Root Page.
ดังนั้นควรเลือก API ตาม UI Type
68. DUI เหมาะกับอะไร
Cfx.re ยกตัวอย่าง
Cinema Screens2D Sprite RenderingGame Render TargetsWorld-space UI
สำหรับ DUI.
ถ้าต้องการ Inventory เต็มหน้าจอ ไม่จำเป็นต้องใช้ DUI
69. Loading Screen ใช้ SendNUIMessage เหมือน HUD ไหม
Loading Screen เป็น NUI Frame พิเศษ และ FiveM มี SEND_LOADING_SCREEN_MESSAGE สำหรับส่ง Message ไปยัง Loading Screen โดยเฉพาะ.
ดังนั้น
Gameplay NUI→ SendNUIMessageLoading Screen→ SendLoadingScreenMessage
ตาม Use Case
70. วิธี Debug NUI ไม่ขึ้นแบบเร็วที่สุด
ขั้นที่ 1 — Resource
ตรวจว่า Resource Started
ขั้นที่ 2 — Manifest
ตรวจ
fxmanifest.luaui_pagefiles
ui_page และ Dependencies ต้องประกาศให้ถูกต้อง.
ขั้นที่ 3 — HTML Test
ใส่
<h1>NUI TEST</h1>
ขั้นที่ 4 — Send Test Message
SendNUIMessage({action = 'test'})
SendNUIMessage ใช้ส่งข้อมูลเข้า NUI Page ของ Resource.
ขั้นที่ 5 — JavaScript
window.addEventListener('message',event => {console.log(event.data);});
Pattern นี้อยู่ใน Fullscreen NUI Documentation.
ขั้นที่ 6 — DevTools
เปิด
nui_devtools
จาก F8.
ขั้นที่ 7 — Focus
ถ้า UI ขึ้นแต่คลิกไม่ได้ ตรวจ SET_NUI_FOCUS.
ขั้นที่ 8 — Callback
ถ้าปุ่มทำงานแต่ Request ค้าง ตรวจ NUI Callback และ cb.
ขั้นที่ 9 — Performance
ใช้
resmon true
ตรวจ Resource CPU/Memory.
ขั้นที่ 10 — Security
Action สำคัญให้ Server Validate ก่อนเปลี่ยน State.
71. ตารางสรุปปัญหา FiveM NUI
| อาการ | จุดที่ควรตรวจ |
|---|---|
| NUI ไม่ขึ้นเลย | Resource / ui_page |
| HTML ไม่โหลด | files / Path |
| UI ขึ้นแต่ไม่มีข้อมูล | SendNUIMessage |
| Message เข้าแต่ UI ไม่เปลี่ยน | JavaScript / DOM |
| UI เปิดแต่คลิกไม่ได้ | NUI Focus |
| Mouse ค้างหลังปิด | Focus Cleanup |
| Callback กดแล้วค้าง | ไม่ตอบ cb |
| Inventory เปิดทับ Phone | Focus/Lifecycle |
| JavaScript Error | NUI DevTools |
| Resource CPU สูง | resmon |
| UI หน่วง | Message/DOM/Rendering |
| DUI ไม่ขึ้น | DUI Lifecycle |
| Loading Screen Message ไม่เข้า | ใช้ API ผิด Frame |
| Action เงิน/Item ไม่ปลอดภัย | Server Validation |
72. Checklist NUI ก่อนขึ้น Production
☐ fxmanifest.lua ถูก☐ ui_page ถูก☐ files ครบ☐ HTML โหลด☐ CSS โหลด☐ JavaScript โหลด☐ SendNUIMessage ทำงาน☐ Message Handler ทำงาน☐ Focus เปิดถูก☐ Focus ปิดถูก☐ Callback ทำงาน☐ Callback ตอบ cb☐ Resource Restart ได้☐ ไม่มี Duplicate Event Handlers☐ ไม่มี Message ที่ส่งซ้ำเกินจำเป็น☐ Responsive☐ 1080p ผ่าน☐ 1440p ผ่าน☐ 4K ผ่าน☐ Ultrawide ผ่าน☐ Server Validate Action สำคัญ☐ resmon ไม่สูงผิดปกติ
73. ตัวอย่าง NUI Resource แบบพื้นฐาน
โครงสร้าง
simple_nui/├── fxmanifest.lua├── client.lua└── html/├── index.html├── style.css└── app.js
fxmanifest.lua
fx_version 'cerulean'game 'gta5'client_script 'client.lua'ui_page 'html/index.html'files {'html/index.html','html/style.css','html/app.js'}
ui_page และ files ทำหน้าที่ตาม Resource Manifest ของ FiveM.
74. ตัวอย่าง client.lua
local menuOpen = falseRegisterCommand('testmenu',function()menuOpen =not menuOpenSetNuiFocus(menuOpen,menuOpen)SendNUIMessage({action =menuOpenand 'open'or 'close'})end)
ตัวอย่างนี้ใช้ SET_NUI_FOCUS และ SendNUIMessage ซึ่งเป็น APIs หลักของ Fullscreen NUI.
75. ตัวอย่าง index.html
<!DOCTYPE html><html><head><meta charset="UTF-8"><linkrel="stylesheet"href="style.css"></head><body><divid="menu"class="hidden"><h1>FiveM NUI</h1><button id="close">Close</button></div><script src="app.js"></script></body></html>
76. ตัวอย่าง app.js รับ Message
const menu =document.getElementById('menu');window.addEventListener('message',function(event) {const data =event.data;if (data.action === 'open') {menu.classList.remove('hidden');}if (data.action === 'close') {menu.classList.add('hidden');}});
FiveM ใช้ Browser message Event สำหรับรับ Messages จาก Game Script ตาม Fullscreen NUI Documentation.
77. NUI ที่ดีควรแบ่ง Layer
แนะนำ Architecture
SERVER↓CLIENT↓UI ADAPTER↓NUI MESSAGE↓UI STATE↓DOM / COMPONENTS
และย้อนกลับ
UI ACTION↓NUI CALLBACK↓CLIENT↓SERVER VALIDATION↓RESULT
แนวทางนี้ช่วยให้ UI ไม่กลายเป็น Source of Truth สำหรับ Gameplay ที่ต้องรักษาความปลอดภัย.
78. สิ่งที่ไม่ควรทำกับ FiveM NUI
หลีกเลี่ยง
SendNUIMessage ทุกข้อมูลทุก FrameRegister Event ซ้ำสร้าง Timer ซ้ำUpdate DOM ทั้งหน้าทุกครั้งเปิด Focus ค้างตลอดไม่คืน Focus ตอนปิด UIไม่ตอบ NUI Callbackเชื่อข้อมูล NUI เพื่อเพิ่มเงินหรือ ItemHard-code เฉพาะ 1920×1080แก้ CSS โดยไม่เปิด NUI DevTools
โดยเฉพาะ Callback ที่ไม่ตอบ cb สามารถ Timeout ได้ และ Gameplay Action ที่มาจาก Client ควรผ่าน Server-side Validation ตาม Security Guidance ของ Cfx.re.
สูตรจำง่ายสำหรับ FiveM NUI
GAME↓MESSAGE↓NUI↓USER↓CALLBACK↓GAME
หรือแบบเต็ม
SERVER↓CLIENT↓SendNUIMessage↓HTML / CSS / JS↓PLAYER↓NUI Callback↓CLIENT↓SERVER
สรุป FiveM NUI คืออะไร
FiveM NUI คือระบบ HTML-based User Interface ของ CitizenFX Framework ที่ช่วยให้ Developer สร้าง Interface ภายใน FiveM ด้วย HTML, CSS และ JavaScript และรองรับ Framework อย่าง React/Angular รวมถึง WebGL ตามความต้องการ.
Fullscreen NUI ถูกแสดงเป็น UI Page Overlay เหนือ Game View และกำหนดผ่าน
ui_page 'html/index.html'
ใน fxmanifest.lua โดย Local UI File และ Dependencies ต้องประกาศใน files.
สำหรับการส่งข้อมูลจาก FiveM Script ไปยังหน้า UI ใช้
SendNUIMessage
แล้ว JavaScript รับข้อมูลผ่าน Browser message Event.
สำหรับการส่งข้อมูลกลับจาก UI เข้า Game ใช้ NUI Callback และต้องตอบ cb เพื่อไม่ให้ Request Timeout.
ถ้า UI ต้องรับ Mouse/Keyboard ใช้
SET_NUI_FOCUS
และสามารถตรวจ Current Focus ด้วย IS_NUI_FOCUSED.
ถ้าต้องการ Render Web UI ลงบน Texture หรือ Object ภายในโลกเกม ให้ดู DUI — Direct-rendered UI ซึ่ง FiveM รองรับแยกจาก Fullscreen NUI.
ถ้า NUI ไม่ขึ้น ให้ตรวจ fxmanifest.lua → ui_page → files → HTML
ถ้า UI ขึ้นแต่ข้อมูลไม่มา ให้ตรวจ SendNUIMessage
ถ้า ข้อมูลเข้าแต่หน้าจอไม่เปลี่ยน ให้ตรวจ JavaScript/DOM ผ่าน nui_devtools.
ถ้า เมาส์ค้างหลังปิด Menu ให้ตรวจ NUI Focus
ถ้า Callback ค้าง ให้ตรวจว่ามีการตอบ cb
และหาก NUI เกี่ยวข้องกับ เงิน, Inventory, Permission หรือ Action สำคัญ อย่าเชื่อค่าจาก Client/UI โดยตรง แต่ให้ Server ตรวจ Gameplay State และเงื่อนไขที่สำคัญก่อน เพราะ Cfx.re เตือนว่า Client สามารถ Trigger Events ได้และแนะนำให้รักษา Server-side Validation.
แนวทางของ comsiam คือแยก FiveM NUI ออกเป็น Data → Message → UI State → Rendering → Callback → Server Validation ให้ชัดตั้งแต่เริ่มพัฒนา เมื่อเกิดปัญหาจะรู้ทันทีว่าต้องตรวจ Data, NUI Message, JavaScript, Focus, Callback หรือ Server Logic แทนการแก้ทุกส่วนพร้อมกัน
Comments
Post a Comment