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

Popular posts from this blog

FiveM ยังน่าเล่นไหม? Enhanced เปลี่ยน FiveM แค่ไหน

FiveM คืออะไร เล่นอย่างไร สำหรับมือใหม่ เริ่มต้นตั้งแต่ศูนย์

วิธีตั้ง Admin Permission ด้วย add_ace และ add_principal FiveM แบบละเอียด