FiveM Speedometer คืออะไร วิธีทำมาตรวัดความเร็วรถ km/h และ mph
FiveM Speedometer คือ HUD สำหรับแสดงข้อมูลของรถที่ผู้เล่นกำลังขับ เช่น ความเร็ว, RPM, Gear, Fuel และสถานะของรถ โดย Speedometer แบบ Custom มักสร้างเป็น NUI แล้วให้ Client Script อ่านข้อมูลจาก Vehicle ก่อนส่งค่ามาแสดงบนหน้าจอ
FiveM มี Native GET_ENTITY_SPEED ซึ่งคืนความเร็วของ Entity ในหน่วย เมตรต่อวินาที (m/s) โดย Cfx.re ระบุว่าสามารถแปลงเป็น km/h ด้วยการคูณ 3.6 และเป็น mph ด้วยการคูณประมาณ 2.236936.
ดังนั้นหัวใจของ Speedometer พื้นฐานสามารถมองเป็น
Vehicle
↓
GetEntitySpeed
↓
m/s
↓
× 3.6
↓
km/h
↓
SendNUIMessage
↓
Speedometer
บทความนี้จาก comsiam จะอธิบายตั้งแต่วิธีอ่านความเร็ว ไปจนถึง RPM, Gear, Fuel, Reverse, km/h, mph และการ Optimize Speedometer ไม่ให้ทำ FPS ตก
① FiveM Speedometer คืออะไร
Speedometer คือส่วนหนึ่งของ Vehicle HUD ที่แสดงความเร็วของรถ
ตัวอย่าง
0 km/h
35 km/h
80 km/h
120 km/h
200 km/h
Custom Speedometer สามารถแสดงข้อมูลเพิ่มเติมได้ เช่น
Speed
RPM
Gear
Fuel
Engine
Seatbelt
Indicators
Handbrake
FiveM มี Native สำหรับข้อมูลรถหลายรายการ เช่น Current RPM, Current Gear และ Fuel Level.
② Speedometer ต่างจาก HUD อย่างไร
HUD เป็นคำกว้างกว่า
HUD
├── Health
├── Armor
├── Hunger
├── Voice
└── Vehicle HUD
└── Speedometer
ดังนั้น Speedometer คือส่วนหนึ่งของ HUD ที่เน้นข้อมูล Vehicle
③ Speedometer ต่างจาก GTA Dashboard อย่างไร
GTA V มี Dashboard ภายในรถและระบบข้อมูล Vehicle ของเกมอยู่แล้ว
ส่วน FiveM Custom Speedometer คือ UI ที่ Server สร้างเพิ่มเติมบนหน้าจอ
FiveM ยังมี Native GET_VEHICLE_DASHBOARD_SPEED สำหรับอ่าน Dashboard Speed ของ Vehicle และ Native Dashboard อื่น ๆ เช่น Dashboard RPM.
④ Native หลักสำหรับหาความเร็วคืออะไร
ใช้
GetEntitySpeed(vehicle)
Cfx.re ระบุว่า GET_ENTITY_SPEED คืนความเร็วปัจจุบันของ Entity เป็นเมตรต่อวินาที.
เพราะ Vehicle เป็น Entity จึงสามารถส่ง Vehicle Handle เข้า Native นี้ได้
⑤ GetEntitySpeed คืนค่าเป็น km/h เลยหรือไม่
ไม่
ค่าที่ได้เป็น
เมตรต่อวินาที
m/s
ตาม Native Reference.
จึงต้อง Convert ก่อนแสดง
⑥ แปลง m/s เป็น km/h อย่างไร
ใช้
km/h = m/s × 3.6
Cfx.re ระบุ Conversion Factor นี้ไว้ใน GET_ENTITY_SPEED โดยตรง.
ตัวอย่าง
local speed = GetEntitySpeed(vehicle) * 3.6
⑦ แปลงเป็น mph อย่างไร
ใช้ประมาณ
mph = m/s × 2.236936
ตาม Cfx.re Native Reference.
ตัวอย่าง
local speed = GetEntitySpeed(vehicle) * 2.236936
⑧ Speedometer ไทยควรใช้ km/h หรือ mph
สำหรับ Interface ภาษาไทยโดยทั่วไป km/h เข้าใจง่ายกว่า
แต่ Custom HUD ที่ให้ผู้เล่นต่างประเทศใช้อาจเพิ่ม Setting
Unit
├── km/h
└── mph
แล้วเก็บค่าความเร็วต้นทางเป็น m/s ก่อน Convert ตอนแสดงผล
⑨ ตัวอย่างอ่านความเร็วแบบพื้นฐาน
local ped = PlayerPedId()
if IsPedInAnyVehicle(ped, false) then
local vehicle = GetVehiclePedIsIn(ped, false)
local speed = GetEntitySpeed(vehicle) * 3.6
print(speed)
end
IS_PED_IN_ANY_VEHICLE ใช้ตรวจว่า Ped อยู่ใน Vehicle หรือไม่ ส่วน GET_ENTITY_SPEED ใช้อ่านความเร็วของ Vehicle Entity.
⑩ ทำไมต้องตรวจว่าผู้เล่นอยู่ในรถก่อน
เพราะ Speedometer มีประโยชน์เมื่อผู้เล่นอยู่ใน Vehicle
แทนที่จะ Query Vehicle Data ตลอดเวลาขณะเดิน สามารถทำ Logic
อยู่ในรถ
→ Update Speedometer
ไม่ได้อยู่ในรถ
→ Hide Speedometer
→ ลดความถี่ Loop
แนวทางปรับ Wait ตาม State ช่วยหลีกเลี่ยงการทำงานทุก Tick เมื่อไม่จำเป็น ซึ่งสอดคล้องกับแนวทางของ Citizen.Wait.
⑪ PlayerPedId คืออะไร
PlayerPedId() ใช้ได้ใน Client Script เพื่ออ้าง Ped ของผู้เล่นปัจจุบัน
จากนั้นจึงตรวจว่าผู้เล่นอยู่ใน Vehicle และหา Vehicle Entity ที่ต้องการอ่านข้อมูล
⑫ GetVehiclePedIsIn ใช้ทำอะไร
ใช้หา Vehicle ที่ Ped กำลังอยู่
Flow จึงเป็น
Player Ped
↓
Ped อยู่ในรถ?
↓
หา Vehicle
↓
อ่าน Speed
ก่อนส่งข้อมูลไป Vehicle HUD
⑬ Speed ควร Round ก่อนแสดงไหม
โดยทั่วไปควรพิจารณา
ถ้าค่า Raw เป็น
82.739194
การแสดง
83 km/h
อ่านง่ายกว่า
ตัวอย่าง
local speed = math.floor((GetEntitySpeed(vehicle) * 3.6) + 0.5)
การ Round เป็นเรื่องของ UI Design ไม่ได้เปลี่ยนค่าความเร็วต้นทางของ Native
⑭ math.floor อย่างเดียวต่างอย่างไร
ถ้าใช้
math.floor(speed)
ค่า
89.9
จะเป็น
89
แต่ถ้าต้องการ Round ใกล้ที่สุดสามารถออกแบบ Logic เพิ่มเอง
⑮ Speedometer แบบ Digital คืออะไร
แสดงตัวเลข เช่น
084
KM/H
ข้อดีคืออ่านเร็วและทำ UI ได้ง่าย
เหมาะกับ HUD แบบ Minimal
⑯ Speedometer แบบ Analog คืออะไร
เป็นมาตรวัดเข็ม
เช่น
0
40
80
120
160
200
จากนั้น JavaScript/CSS แปลงความเร็วไปเป็น Rotation ของเข็ม
ตัวอย่างแนวคิด
speed
↓
normalize
↓
angle
↓
rotate needle
⑰ Speedometer แบบ Hybrid คืออะไร
ใช้ทั้ง
Analog Gauge
+
Digital Speed
ผู้เล่นจึงเห็นทั้งเข็มและตัวเลข
แต่ UI มี Elements มากขึ้น จึงควรวัด Performance จริงหากใช้ Animation หรือ Effects จำนวนมาก
⑱ GET_VEHICLE_DASHBOARD_SPEED คืออะไร
FiveM มี
GET_VEHICLE_DASHBOARD_SPEED
สำหรับอ่าน Dashboard Speed ของ Vehicle.
อย่างไรก็ตาม Custom Speedometer ทั่วไปสามารถใช้ GET_ENTITY_SPEED แล้ว Convert หน่วยเองได้ ทำให้ควบคุม km/h และ mph ได้ตรงไปตรงมา.
⑲ Speedometer ควรใช้ GET_ENTITY_SPEED หรือ Dashboard Speed
สำหรับ HUD ที่ต้องการค่าความเร็ว Entity โดยตรง
GET_ENTITY_SPEED
เป็นวิธีที่ชัดและมี Conversion m/s → km/h/mph ระบุใน Cfx.re Docs.
Dashboard natives เหมาะเมื่อคุณต้องการข้อมูลที่อิง Dashboard System โดยตรง.
⑳ RPM คืออะไร
RPM ใช้แสดงรอบการทำงานของเครื่องยนต์ใน Vehicle HUD
FiveM มี
GET_VEHICLE_CURRENT_RPM
ซึ่งคืนค่าประเภท Float สำหรับ RPM State ปัจจุบันของ Vehicle.
㉑ อ่าน RPM อย่างไร
ตัวอย่าง
local rpm = GetVehicleCurrentRpm(vehicle)
Native นี้มีอยู่โดยตรงใน FiveM Vehicle API.
จากนั้น HUD สามารถนำค่าไปสร้าง
RPM Bar
Needle
Progress Circle
ตาม Design
㉒ GET_VEHICLE_DASHBOARD_RPM คืออะไร
FiveM ยังมี
GET_VEHICLE_DASHBOARD_RPM
โดย Native Reference ระบุค่าประมาณ 0 ถึง ~1.1 สำหรับตำแหน่ง Gauge RPM บน Dashboard ของรถผู้เล่น.
ดังนั้นต้องรู้ก่อนว่าคุณต้องการ Current Vehicle RPM State หรือ Dashboard Gauge Value
㉓ Gear คืออะไรใน Speedometer
Gear ใช้แสดงเกียร์ เช่น
R
N
1
2
3
4
5
6
FiveM มี
GET_VEHICLE_CURRENT_GEAR
สำหรับอ่าน Current Gear ของ Vehicle.
㉔ ตัวอย่างอ่าน Gear
local gear = GetVehicleCurrentGear(vehicle)
จากนั้นส่งค่าเข้า NUI
SendNUIMessage({
action = 'gear',
value = gear
})
SendNUIMessage เป็น Function ของ FiveM สำหรับส่ง Table Data ไปยัง NUI.
㉕ เกียร์ R ตรวจอย่างไร
อย่าตั้งสมมติฐานจาก Current Gear เพียงค่าเดียวโดยไม่ทดสอบ Vehicle Behavior
หากต้องการตรวจทิศการเคลื่อนที่ FiveM มี GET_ENTITY_SPEED_VECTOR ซึ่งเมื่อใช้ Relative Vector สามารถดูทิศทางความเร็วสัมพันธ์กับ Entity ได้ โดย Cfx.re ระบุว่าสามารถใช้ค่าแกน Y เพื่อแยกการเคลื่อนที่ไปข้างหน้ากับถอยหลังได้.
㉖ GetEntitySpeedVector ช่วยตรวจ Reverse อย่างไร
แนวคิด
local velocity = GetEntitySpeedVector(vehicle, true)
if velocity.y < 0.0 then
-- vehicle moving backwards
end
Cfx.re ระบุว่าเมื่อ relative เปิดอยู่ ค่า Y เชิงลบสามารถใช้บอกว่ารถเคลื่อนที่ย้อนทาง ขณะที่ค่าบวกคือไปข้างหน้า.
㉗ Fuel แสดงบน Speedometer ได้ไหม
ได้
FiveM มี
GET_VEHICLE_FUEL_LEVEL
สำหรับอ่าน Fuel Level ของ Vehicle.
ตัวอย่าง
local fuel = GetVehicleFuelLevel(vehicle)
㉘ Fuel HUD กับ Fuel Script เหมือนกันไหม
ไม่จำเป็น
Speedometer อาจมีหน้าที่เพียงแสดงค่าที่ระบบ Fuel ใช้อยู่
ส่วน Logic เช่น
การลดน้ำมัน
เติมน้ำมัน
ราคาน้ำมัน
ปั๊มน้ำมัน
สามารถอยู่ใน Resource อื่น
ดังนั้น UI กับ Gameplay Logic ควรแยกกัน
㉙ Native Fuel กับ Custom Fuel Resource ต้องระวังอะไร
หาก Server ใช้ Custom Fuel Resource ต้องตรวจว่า Resource นั้นใช้ค่า Vehicle Fuel Level โดยตรงหรือมี State ของตัวเอง
ไม่ควรให้ HUD อ่าน Source A แต่ Fuel Script เขียน Source B เพราะค่าบนหน้าจออาจไม่ตรงกับ Gameplay
㉚ Seatbelt เป็น Speed Native ไหม
ไม่
Seatbelt เป็น Gameplay State ที่ Server Script มักสร้างขึ้นเอง เช่น
seatbelt = true
หรือ
seatbelt = false
แล้วส่งให้ HUD แสดง Icon
ดังนั้น Speedometer ไม่ควรเดาสถานะ Seatbelt จากความเร็วรถเพียงอย่างเดียว
㉛ Engine State แสดงได้ไหม
ได้หาก Vehicle HUD ต้องการ
เช่น
Engine ON
Engine OFF
Engine Damaged
แต่ควรแยก Engine Gameplay Logic ออกจาก UI เช่นเดียวกับ Fuel และ Seatbelt
㉜ Dashboard Lights แสดงได้ไหม
FiveM มี GET_VEHICLE_DASHBOARD_LIGHTS ซึ่งคืนสถานะ Dashboard Lights เป็น Bit Set และเอกสารระบุสถานะเช่น Indicator Left, Indicator Right, Handbrake, Engine และ ABS.
จึงสามารถทำ Vehicle HUD ที่ละเอียดกว่ามาตรวัดความเร็วอย่างเดียวได้
㉝ ไฟเลี้ยวแสดงบน HUD ได้ไหม
ได้ หาก Script อ่าน Dashboard Light State แล้ว Decode Bits ที่เกี่ยวข้อง
Cfx.re ระบุ Flags เช่น
indicator_left = 1
indicator_right = 2
handbrakeLight = 4
engineLight = 8
ABSLight = 16
ใน Native นี้.
㉞ Speedometer ต้องแสดงทุก Vehicle ไหม
ไม่จำเป็น
Server สามารถกำหนด
Cars → Show
Motorcycles → Show
Boats → Custom
Aircraft → Custom HUD
Bicycles → Hide
ตาม Gameplay Design
ไม่ควรคิดว่า UI แบบรถยนต์เหมาะกับ Vehicle ทุก Class
㉟ Speedometer ควรแสดงตอน Passenger ไหม
ขึ้นอยู่กับ Server
แบบที่ 1
ทุกคนในรถเห็น
แบบที่ 2
เฉพาะ Driver เห็น
ถ้าต้องการเฉพาะ Driver ให้ตรวจ Seat ของ Player ก่อนเปิด Vehicle HUD
ช่วยลด UI/Calculation ที่ Passenger ไม่ได้ใช้
㊱ Speedometer ทำด้วย NUI ได้ไหม
ได้
FiveM Fullscreen NUI สามารถ Overlay หน้า UI เหนือเกม และ Resource กำหนด NUI ผ่าน ui_page ใน Manifest.
โครงสร้างอาจเป็น
speedometer/
├── fxmanifest.lua
├── client.lua
└── html/
├── index.html
├── style.css
└── app.js
㊲ Flow ของ NUI Speedometer
Client Script
↓
Vehicle Data
↓
Speed / RPM / Gear / Fuel
↓
SendNUIMessage
↓
JavaScript
↓
HTML/CSS
↓
Speedometer
FiveM รองรับ SendNUIMessage สำหรับส่งข้อมูลจาก Lua ไปยัง NUI โดยตรง.
㊳ ตัวอย่างส่งข้อมูล Vehicle ไป NUI
SendNUIMessage({
action = 'vehicle',
speed = speed,
rpm = rpm,
gear = gear,
fuel = fuel
})
ข้อมูลที่ส่งเป็น Table และ NUI สามารถนำไป Render ต่อได้.
㊴ JavaScript รับข้อมูลอย่างไร
Fullscreen NUI ใช้ Browser-side Message Event เพื่อรับข้อมูลที่ Script ส่งเข้า UI.
แนวคิด
window.addEventListener('message', function(event) {
const data = event.data;
if (data.action === 'vehicle') {
// update speedometer
}
});
㊵ Speedometer ควร Update ทุก Frame ไหม
ไม่จำเป็นต้องตอบแบบตายตัว
FiveM ระบุว่า Wait(0) ทำให้ Thread Yield ไปจนถึง Tick ถัดไป และเหมาะกับ Logic ที่ต้องทำงานทุก Frame แต่ถ้างานไม่จำเป็นต้องทุก Frame สามารถเพิ่มเวลารอหรือเปลี่ยนตาม State ได้.
สำหรับ Speedometer ต้องหาจุดสมดุลระหว่าง
ความลื่น
vs
CPU/NUI Work
㊶ Wait(1000) เหมาะกับ Speedometer ไหม
โดยทั่วไปจะทำให้ค่าความเร็วอัปเดตเป็นช่วงใหญ่เกินสำหรับ HUD ที่ต้องดูต่อเนื่อง
ตัวอย่าง
40 km/h
↓
1 วินาที
↓
78 km/h
↓
1 วินาที
↓
110 km/h
Speedometer จะดูเหมือนกระโดด
ควรใช้ Interval ที่เหมาะกับ UX แล้ววัด Performance จริง
㊷ Wait(0) ผิดไหม
ไม่
งานที่ต้อง Update ทุก Frameสามารถใช้ Wait(0) ได้ตาม Cfx.re Documentation.
แต่สิ่งที่ไม่ควรทำคือเอางานจำนวนมากที่ไม่จำเป็นไปใส่ใน Loop นั้น
เช่น Query
Money
Job
Hunger
Player Name
พร้อม Speed ทุก Tick
㊸ Dynamic Sleep เหมาะกับ Speedometer มาก
ตัวอย่าง
CreateThread(function()
while true do
local sleep = 1000
local ped = PlayerPedId()
if IsPedInAnyVehicle(ped, false) then
sleep = 50
local vehicle = GetVehiclePedIsIn(ped, false)
local speed = GetEntitySpeed(vehicle) * 3.6
-- update speedometer
end
Wait(sleep)
end
end)
แนวคิดการปรับ Wait ตาม State ช่วยหลีกเลี่ยงการทำงานถี่เมื่อ Feature ไม่ถูกใช้งาน.
ตัวเลขเป็นเพียงตัวอย่าง ไม่ใช่ค่ามาตรฐานที่ทุก HUD ต้องใช้
㊹ ทำไม Speedometer กระตุก
สาเหตุที่ควรตรวจ เช่น
Update Interval ช้าเกิน
NUI Message มาไม่สม่ำเสมอ
JavaScript Animation
DOM Rendering
Vehicle Data Calculation
Client FPS ต่ำ
ต้องแยกก่อนว่า เกม FPS ตก หรือเพียง ตัวเลข Speed Update ช้า
㊺ Speedometer กระโดดแต่เกมยัง 120 FPS
มีโอกาสสูงว่าเป็น Update/Interpolation Problem มากกว่าตัวเกม FPS
เช่น
Wait(500)
ทำให้ NUI ได้ข้อมูลใหม่เพียงประมาณ 2 ครั้งต่อวินาที
แก้ที่ Refresh Strategy ก่อน Optimize GPU
㊻ เกมทั้งเกมกระตุกเมื่อขึ้นรถ
ให้ตรวจ Resource Performance
FiveM มี
resmon true
สำหรับดู CPU และ Memory ของ Resources.
ถ้า Vehicle HUD Resource ใช้เวลาสูงเฉพาะตอนขึ้นรถ ให้ตรวจ Loop/Vehicle Modules ของ Resource นั้น
㊼ ใช้ resmon ตรวจ Speedometer อย่างไร
เปิด
resmon true
แล้วเปรียบเทียบ
เดิน
vs
ขับรถ
หาก Resource
vehicle_hud
เพิ่ม CPU Usage ชัดเจนตอนเข้า Vehicle มีเหตุผลให้ตรวจ Code ภายใน Resource นั้นก่อน.
㊽ Speedometer Resource CPU สูงเกิดจากอะไรได้บ้าง
ตัวอย่าง
Native Calls จำนวนมากทุก Tick
หลาย Threads ทำ Vehicle Data ซ้ำกัน
คำนวณ Street/Compass ซ้ำ
SendNUIMessage หลายครั้งต่อ Tick
Framework Query
Event ถูก Register ซ้ำ
อย่าคิดว่า GetEntitySpeed เพียงหนึ่งครั้งเป็นต้นเหตุทันที
ต้อง Profile ทั้ง Resource
㊾ ใช้ Profiler ได้ไหม
ได้
เมื่อรู้ว่า Resource มีปัญหาแต่ไม่รู้ว่า Thread ไหนหนัก ควรใช้ FiveM Profiler เพื่อวิเคราะห์ Runtime
FiveM Documentation มี Profiler สำหรับตรวจ Resource/Script Performance และหา Code Path ที่ใช้เวลาสูง.
㊿ Speedometer ทำ FPS ตกเพราะ NUI ได้ไหม
มีโอกาส
เพราะ Fullscreen NUI เป็น UI Overlay ที่ Render บน Client.
ถ้า Client Script ดูเบาแต่เปิด Speedometer แล้ว FPS ยังลด ให้ตรวจ
JavaScript
DOM
CSS
Animations
Effects
เพิ่มเติม
51. CSS เข็มหมุนทำอย่างไร
แนวคิด
Speed
↓
Percent
↓
Degree
↓
transform: rotate(...)
ไม่ควรเขียน DOM ใหม่ทั้ง Speedometer ทุกครั้งเพียงเพื่อเปลี่ยนเข็ม
Update เฉพาะ Element ที่เปลี่ยนพอ
52. ตัวเลขความเร็วควร Update เฉพาะตอนเปลี่ยนไหม
สามารถทำได้
ตัวอย่าง
local lastSpeed = -1
if speed ~= lastSpeed then
lastSpeed = speed
SendNUIMessage({
action = 'speed',
value = speed
})
end
เพราะ SendNUIMessage ส่งข้อมูลไป NUI ทุกครั้งที่ถูกเรียก.
53. RPM ควรส่งพร้อม Speed ไหม
ถ้าทั้งสองต้อง Update ความถี่ใกล้กัน สามารถ Batch
SendNUIMessage({
action = 'vehicleData',
speed = speed,
rpm = rpm
})
ลด Logic กระจัดกระจาย
แต่ไม่จำเป็นต้องใส่ Money/Job เข้า Message นี้
54. Fuel ไม่จำเป็นต้อง Update ถี่เท่า Speed
โดยทั่วไป Fuel เปลี่ยนช้ากว่าความเร็ว
จึงสามารถใช้
Speed/RPM → Fast
Fuel → Slower
หรือส่งเมื่อค่าที่แสดงเปลี่ยน
ช่วยลด NUI Work ที่ไม่จำเป็น
55. Gear ต้อง Update บ่อยแค่ไหน
Gear เปลี่ยนเป็นช่วง ๆ
ดังนั้นสามารถ Cache Gear เดิม
gear != lastGear
→ ส่ง Update
แทนการ Render Gear ตัวเดิมทุก Tick
FiveM มี GET_VEHICLE_CURRENT_GEAR สำหรับอ่านค่า Gear ปัจจุบัน.
56. Speedometer ควร Hide ตอนลงรถทันที
ควรมี State ชัด
Vehicle Enter
→ Show
Vehicle Exit
→ Hide
และเมื่อลงรถควรหยุด Fast Vehicle Update Loop หรือกลับไปใช้ Sleep ที่นานขึ้น
57. Speedometer ไม่หายหลังลงรถเกิดจากอะไร
ตรวจ
IsPedInAnyVehicle
Vehicle State
NUI visibility
lastVehicle
หาก Script หยุด Query Vehicle แต่ไม่ได้ส่ง
hide
ไป NUI UI อาจยังค้างบนหน้าจอ
58. Speedometer หายตอนเข้า Vehicle
ตรวจ
Vehicle detection
NUI show message
JavaScript
CSS
ถ้า Player HUD ปกติแต่ Vehicle HUD ไม่ขึ้น ปัญหาน่าจะอยู่ Vehicle-specific Layer
59. Speedometer แสดง 0 ตลอด
ตรวจตามนี้
Vehicle Handle ถูก?
↓
GetEntitySpeed ได้ค่าไหม?
↓
Conversion ถูก?
↓
SendNUIMessage ส่งไหม?
↓
JavaScript รับไหม?
GET_ENTITY_SPEED ต้องรับ Entity ที่ต้องการอ่านความเร็ว.
60. Speedometer แสดงเร็วเกินจริง
ตรวจ Conversion
ข้อผิดพลาดเช่น
m/s × 3.6 × 3.6
ทำให้ค่ามากเกินจริง
สำหรับ km/h ใช้เพียง
m/s × 3.6
ตาม Cfx.re Docs.
61. Speedometer แสดงช้าเกินจริง
ตรวจว่าไม่ได้เอาค่า m/s ไปแสดงแล้วใส่ Label km/h
ตัวอย่าง
27.8 m/s
จริง ๆ คือประมาณ
100 km/h
เพราะต้องคูณ 3.6.
62. mph กับ km/h สลับกันได้อย่างไร
เก็บ Setting เช่น
local unit = 'kmh'
แล้ว
if unit == 'kmh' then
speed = rawSpeed * 3.6
else
speed = rawSpeed * 2.236936
end
ทั้งสอง Conversion Factors มีระบุใน FiveM Native Reference.
63. Reverse ควรแสดง R อย่างไร
อย่าพึ่ง Gear อย่างเดียว
สามารถตรวจ Relative Velocity
local velocity = GetEntitySpeedVector(vehicle, true)
local reverse = velocity.y < 0.0
โดย Cfx.re ระบุว่า Relative Speed Vector สามารถใช้ค่า Y เชิงลบเพื่อตรวจการเคลื่อนที่ย้อนทางได้.
64. รถหยุดควรแสดง N หรือ 1
ขึ้นอยู่กับ Gear/Data และ UI Design
อย่า Hard-code ว่า
speed = 0
→ N
เพราะรถสามารถหยุดอยู่ขณะเข้าเกียร์เดินหน้าหรือถอยหลังได้
ควรอ่าน Gear State ที่มีอยู่จริงและใช้ Reverse Detection แยกตามความต้องการ
65. Handbrake Icon ทำได้ไหม
FiveM Dashboard Lights Native มี Handbrake Light Flag อยู่ใน Bit Set ที่คืนมา.
สามารถ Decode แล้วแสดง
P
BRAKE
ตาม Design ของ HUD ได้
66. Engine Warning Icon ทำได้ไหม
Dashboard Lights Native ยังมี Engine Light Flag ตามเอกสาร Cfx.re.
HUD ที่ต้องการ Dashboard Simulation จึงสามารถนำข้อมูลนี้มาใช้ร่วมกับ Speed/RPM ได้
67. ABS Icon ทำได้ไหม
มี ABS Light อยู่ใน Dashboard Lights Bit Set ตาม Native Reference.
แต่ควรแสดงตามข้อมูลที่ Game Return จริง ไม่สร้าง Logic จากความเร็วเพียงอย่างเดียว
68. Speedometer สำหรับรถทุกชนิดต้องเหมือนกันไหม
ไม่ควร
ตัวอย่าง
Car
→ Speed / RPM / Gear / Fuel
Motorcycle
→ Speed / RPM / Fuel
Boat
→ Speed / Fuel
Aircraft
→ ควรมี Flight-specific HUD
Custom HUD ที่ดีสามารถเปิด Module ตาม Vehicle Type/Gameplay ได้
69. Speedometer กับ Minimap ควรเชื่อมกันไหม
ไม่จำเป็น
บาง Server เปิด
Minimap
+
Speedometer
ตอนเข้า Vehicleพร้อมกัน
แต่ควรแยก State Ownership
เพื่อไม่ให้ Speedometer Resource และ Minimap Resource สั่งเปิด/ปิด Radar แข่งกัน
70. Speedometer กับ Seatbelt ควรเป็น Resource เดียวกันไหม
ขึ้นอยู่กับ Architecture
สามารถมี
vehicle_hud
เป็น UI แล้วรับ State จาก
seatbelt resource
fuel resource
vehicle resource
แทนรวม Gameplay Logic ทั้งหมดเข้ากับ HUD
ทำให้เปลี่ยน UI ได้ง่ายโดยไม่กระทบระบบ Seatbelt/Fuel
71. Speedometer ต้องใช้ ESX ไหม
ไม่
Native เช่น
GET_ENTITY_SPEED
GET_VEHICLE_CURRENT_RPM
GET_VEHICLE_CURRENT_GEAR
GET_VEHICLE_FUEL_LEVEL
เป็น FiveM/GTA Vehicle APIs ไม่ได้ขึ้นกับ ESX.
ESX จะเกี่ยวข้องเมื่อ Vehicle HUD ต้องดึงข้อมูลจากระบบอื่นของ Framework
72. Speedometer ต้องใช้ QBCore ไหม
ไม่จำเป็นเช่นเดียวกัน
Standalone Speedometer สามารถอ่าน Vehicle Data ผ่าน FiveM Natives ได้โดยตรง.
ส่วน Fuel/Seatbelt หรือ Player Metadata อาจเชื่อม Framework ตาม Resource ที่ Server ใช้
73. Speedometer Resource มี fxmanifest.lua ไหม
ถ้าเป็น Resource ปกติ FiveM ใช้ fxmanifest.lua เป็น Manifest ใน Resource Folder.
ถ้าใช้ Fullscreen NUI ต้องกำหนด ui_page และ UI Files ที่เกี่ยวข้องใน Resource Manifest.
74. ตัวอย่าง fxmanifest สำหรับ Speedometer
fx_version 'cerulean'
game 'gta5'
client_script 'client.lua'
ui_page 'html/index.html'
files {
'html/index.html',
'html/style.css',
'html/app.js'
}
โครงสร้างนี้สอดคล้องกับ Fullscreen NUI Resource Structure ที่ Cfx.re อธิบายไว้.
75. Speedometer ไม่ขึ้นหลังติดตั้ง
ตรวจ
Resource Root
fxmanifest.lua
ui_page
files
client.lua
NUI JavaScript
จากนั้นตรวจว่า Resource Start แล้วหรือไม่
FiveM Server Commands รองรับ refresh, ensure, restart และคำสั่ง Resource Management อื่น ๆ.
76. เพิ่ง Copy Resource เข้า Server ใช้อะไร
ใช้
refresh
เพื่อ Rescan Resources และ Manifests แล้ว
ensure speedometer
เพื่อ Start Resource
ตาม FiveM Server Commands Documentation.
77. Speedometer ขึ้นหลัง ensure แต่ Restart Server แล้วหาย
ตรวจว่า Resource ถูก Start ใน Startup Configuration หรือไม่
เช่น
ensure speedometer
ต้องอยู่ใน Resource Startup Flow ที่ Server ใช้งาน
ensure จะ Start Resource หากยังไม่ Started หรือ Restart หาก Started อยู่.
78. NUI Speedometer ไม่ขึ้นแต่ Script อ่าน Speed ได้
ถ้า Log แสดง
speed = 80
แต่หน้าจอไม่มี UI
ให้เน้น
SendNUIMessage
JavaScript message handler
CSS visibility
ui_page
มากกว่า Vehicle Native เพราะคุณพิสูจน์แล้วว่า Speed Data มีอยู่
79. Speedometer UI ขึ้นแต่เลขไม่เปลี่ยน
ตรวจ
Client Loop
↓
SendNUIMessage
↓
JavaScript
↓
DOM
SendNUIMessage ต้องถูกเรียกเมื่อข้อมูลใหม่ต้องถูกส่งเข้า UI.
80. วิธี Debug Speedometer ที่เร็วที่สุด
ขั้นที่ 1 — ตรวจ Player อยู่ Vehicle
ใช้
IS_PED_IN_ANY_VEHICLE
ซึ่ง FiveM คืน Boolean ว่า Ped อยู่ใน Vehicle หรือกำลังเข้า Vehicle ตาม Parameter ที่ใช้.
ขั้นที่ 2 — หา Vehicle
ขั้นที่ 3 — อ่าน Raw Speed
local raw = GetEntitySpeed(vehicle)
ค่าควรเป็น m/s.
ขั้นที่ 4 — Convert
local kmh = raw * 3.6
ขั้นที่ 5 — Print
ดูใน F8 ว่าค่าเปลี่ยนหรือไม่
ขั้นที่ 6 — ส่ง NUI
SendNUIMessage(...)
ขั้นที่ 7 — Console.log ใน NUI
ตรวจ Message
ขั้นที่ 8 — ตรวจ CSS/DOM
ขั้นที่ 9 — ถ้ากระตุก
เปิด
resmon true
เพื่อตรวจ Resource CPU/Memory.
ขั้นที่ 10 — Optimize Loop
ใช้ Wait และ State-based Update ตามสิ่งที่ UI ต้องการ.
ตารางสรุปปัญหา FiveM Speedometer
| อาการ | จุดที่ควรตรวจ |
|---|---|
| Speedometer ไม่ขึ้น | Resource / NUI |
| ขึ้นแต่ 0 ตลอด | Vehicle / Speed Native |
| ความเร็วต่ำกว่าจริง | ลืมแปลง m/s |
| ความเร็วสูงเกินจริง | Conversion ซ้ำ |
| mph ผิด | Conversion Factor |
| ตัวเลขกระโดด | Update Interval |
| FPS ตกตอนขึ้นรถ | Vehicle HUD Loop |
| RPM ไม่ขยับ | RPM Native/UI |
| Gear ไม่เปลี่ยน | Gear Data |
| Reverse ไม่ถูก | Relative Velocity |
| Fuel ไม่เปลี่ยน | Fuel Data Source |
| Seatbelt ไม่เปลี่ยน | Seatbelt Resource State |
| ลงรถแล้ว HUD ค้าง | Vehicle Visibility |
| Restart แล้วไม่ขึ้น | Resource Startup |
| Script เบาแต่ FPS ลด | NUI Rendering |
| HUD Resource CPU สูง | Client Loop |
Checklist Speedometer ก่อนขึ้น Production
☐ GetEntitySpeed ถูก
☐ km/h × 3.6
☐ mph × 2.236936
☐ Round ตัวเลขถูก
☐ RPM ถูก
☐ Gear ถูก
☐ Reverse ถูก
☐ Fuel ถูก
☐ Driver/Passenger State ถูก
☐ เข้า Vehicle แล้ว Show
☐ ลง Vehicle แล้ว Hide
☐ NUI Message ไม่ส่งเกินจำเป็น
☐ ไม่มี Loop ขณะเดินโดยไม่จำเป็น
☐ Resource Restart ได้
☐ 1080p ใช้งานได้
☐ 1440p ใช้งานได้
☐ 4K ใช้งานได้
☐ Ultrawide ใช้งานได้
☐ resmon ไม่สูงผิดปกติ
ตัวอย่าง Speedometer แบบพื้นฐาน
local lastSpeed = -1
CreateThread(function()
while true do
local sleep = 1000
local ped = PlayerPedId()
if IsPedInAnyVehicle(ped, false) then
sleep = 50
local vehicle = GetVehiclePedIsIn(ped, false)
local speed = math.floor(
(GetEntitySpeed(vehicle) * 3.6) + 0.5
)
if speed ~= lastSpeed then
lastSpeed = speed
SendNUIMessage({
action = 'speed',
value = speed,
unit = 'km/h'
})
end
else
if lastSpeed ~= -1 then
lastSpeed = -1
SendNUIMessage({
action = 'hideVehicleHud'
})
end
end
Wait(sleep)
end
end)
ตัวอย่างนี้ใช้ IS_PED_IN_ANY_VEHICLE, GET_ENTITY_SPEED, Conversion km/h และ SendNUIMessage ตาม APIs ที่ FiveM มีให้ ส่วน Interval เป็นเพียงค่าตัวอย่างที่ควรปรับตาม Resource จริง.
ตัวอย่าง Speed + RPM + Gear + Fuel
local vehicle = GetVehiclePedIsIn(PlayerPedId(), false)
local data = {
speed = math.floor((GetEntitySpeed(vehicle) * 3.6) + 0.5),
rpm = GetVehicleCurrentRpm(vehicle),
gear = GetVehicleCurrentGear(vehicle),
fuel = GetVehicleFuelLevel(vehicle)
}
SendNUIMessage({
action = 'vehicleData',
speed = data.speed,
rpm = data.rpm,
gear = data.gear,
fuel = data.fuel
})
FiveM มี Native สำหรับ Speed, Current RPM, Current Gear และ Fuel Level โดยตรง.
Speedometer ที่ดีควร Optimize อย่างไร
ใช้แนวคิด
ไม่อยู่รถ
→ Sleep นาน
→ Vehicle HUD OFF
อยู่รถ
→ Update Vehicle Data
ค่าไม่เปลี่ยน
→ ไม่ต้อง Render ซ้ำ
ค่าเปลี่ยน
→ ส่ง NUI Update
และอย่า Query ข้อมูลที่ไม่เกี่ยวกับ Vehicle ทุก Tick
FiveM Citizen.Wait รองรับการกำหนดเวลาหยุด Thread และเหมาะกับการควบคุม Update Frequency ตาม Logic ของ Resource.
ถ้า Speedometer ทำ FPS ตกต้องทำอย่างไร
ลำดับคือ
① A/B Test HUD ON/OFF
② เปิด resmon
③ ดู Resource CPU/Memory
④ ตรวจ Vehicle Loop
⑤ ตรวจ Native Calls
⑥ ตรวจ Message Frequency
⑦ ตรวจ NUI
⑧ Profile หากยังหาไม่เจอ
FiveM Resource Monitor ใช้ดู CPU/Memory ของ Resources และเหมาะสำหรับวิเคราะห์ปัญหา Performance ระหว่าง Gameplay.
สิ่งที่ไม่ควรทำกับ FiveM Speedometer
หลีกเลี่ยง
Query Money ทุก Tick พร้อม Speed
Query Job ทุก Tick
Send NUI ค่าเดิมซ้ำตลอด
ทำ Vehicle Logic ตอนผู้เล่นเดิน
ใช้ Wait(1000) แล้วหวังให้ Speed ลื่น
ใช้ Wait(0) กับงานหนักทุกอย่าง
แสดง Fuel คนละ Source กับ Fuel Script
ใช้ Gear อย่างเดียวตัดสิน Reverse
มี Speedometer สอง Resource พร้อมกัน
เปลี่ยน HUD ใหม่ก่อนตรวจ resmon
สูตรจำง่ายสำหรับ FiveM Speedometer
PED
↓
VEHICLE
↓
SPEED
↓
CONVERT
↓
HUD
และสำหรับ Speedometer เต็มรูปแบบ
Vehicle
├── Speed
├── RPM
├── Gear
├── Fuel
└── Vehicle State
↓
NUI
สรุป FiveM Speedometer คืออะไร
FiveM Speedometer คือ Vehicle HUD สำหรับแสดงความเร็วและข้อมูลรถ โดยสามารถสร้างจาก FiveM Vehicle Natives ร่วมกับ NUI ได้
Native พื้นฐานที่สุดคือ
GET_ENTITY_SPEED
ซึ่ง Cfx.re ระบุว่าคืนความเร็วเป็นเมตรต่อวินาที จากนั้นคูณ 3.6 เพื่อแสดง km/h หรือ 2.236936 เพื่อแสดง mph.
ถ้าต้องการ Speedometer ที่ละเอียดขึ้น FiveM ยังมี
GET_VEHICLE_CURRENT_RPM
GET_VEHICLE_CURRENT_GEAR
GET_VEHICLE_FUEL_LEVEL
สำหรับ RPM, Gear และ Fuel ตามลำดับ.
หากต้องการตรวจว่ารถกำลังถอยหลัง สามารถใช้ GET_ENTITY_SPEED_VECTOR แบบ Relative และตรวจทิศทางแกน Y ได้ โดย Cfx.re ระบุว่าค่าเชิงลบสามารถใช้แยกการเคลื่อนที่ย้อนทางได้.
จากนั้น Custom Speedometer สามารถส่งข้อมูลเหล่านี้เข้า Fullscreen NUI ผ่าน SendNUIMessage แล้วใช้ HTML/CSS/JavaScript แสดงตัวเลข เข็ม RPM, Gear หรือ Fuel Gauge บนหน้าจอ.
ถ้า Speedometer แสดงค่าต่ำกว่าจริง ให้ตรวจว่าคุณลืมแปลงจาก m/s เป็น km/h หรือไม่
ถ้า ตัวเลขกระโดดแต่ FPS ปกติ ให้ตรวจ Update Interval
ถ้า เข้า Vehicle แล้วทั้งเกม FPS ลด ให้ใช้ resmon true ตรวจ Resource CPU/Memory ก่อน และค่อย Optimize Client Loop/NUI ตามผลที่วัดได้.
หากผู้เล่นไม่ได้อยู่ในรถ ควรหยุดหรือชะลอ Vehicle-specific Processing แทนการ Query Speed, RPM, Gear และ Fuel ต่อเนื่องตลอดเวลา โดย Citizen.Wait สามารถใช้ควบคุมความถี่ Thread ตาม State ของ Resource ได้.
แนวทางของ comsiam คือทำ Speedometer โดยแยก Vehicle Data → HUD State → NUI Rendering ออกจากกัน และ Update แต่ละข้อมูลตามความถี่ที่จำเป็นจริง Speed ต้องตอบสนองเร็ว แต่ Gear, Fuel และข้อมูลอื่นไม่จำเป็นต้อง Render ซ้ำทุก Frame วิธีนี้ช่วยให้ Speedometer ดูลื่น ข้อมูลแม่น และไม่เพิ่ม Client Load โดยไม่จำเป็น
Comments
Post a Comment