FiveM Entity คืออะไร
FiveM Entity คือสิ่งที่มีตัวตนอยู่ในโลกของ GTA V/FiveM และสามารถถูกอ้างอิงหรือจัดการด้วย Script ได้ เช่น Player Ped, NPC, Vehicle และ Object ต่าง ๆ
ตัวอย่าง Entity ที่พบมากที่สุดคือ
Ped
Vehicle
Object
เช่น Player Character เป็น Ped Entity
local ped =
PlayerPedId()
รถที่ Player กำลังขับก็เป็น Vehicle Entity
local vehicle =
GetVehiclePedIsIn(
ped,
false
)
จากนั้น Entity สามารถถูกนำไปใช้กับ Native เช่น
GetEntityCoords(entity)
GetEntityHeading(entity)
DoesEntityExist(entity)
แต่สำหรับ Multiplayer สิ่งสำคัญมากคือ Entity Handle กับ Network ID ไม่ใช่สิ่งเดียวกัน
ถ้าต้องอ้าง Entity ข้าม Client หรือระหว่าง Client กับ Server ต้องเข้าใจ Network ID, Scope และ Entity Ownership เพิ่มเติม
① FiveM Entity คืออะไร
ใน FiveM คำว่า Entity ใช้อ้างถึง Game Object ที่มีตัวตนในโลกเกม
ตัวอย่างหลักคือ
Entity
├── Ped
├── Vehicle
└── Object
Ped, Vehicle และ Object จึงถือเป็น Entity ประเภทต่าง ๆ
Native หลายตัวใช้ Parameter แบบ Entity
เช่น
GetEntityCoords(entity)
จึงสามารถใช้กับ Ped, Vehicle หรือ Object ที่เหมาะสมได้
② Ped Entity คืออะไร
Ped คือ Character Entity
ตัวอย่าง
Player Character
Civilian NPC
Police NPC
Mission NPC
Player ของเราฝั่ง Client สามารถหา Ped ได้ด้วย
local ped =
PlayerPedId()
ค่า ped ที่ได้คือ Entity Handle ของ Player Ped ใน Client Context นั้น
③ Vehicle Entity คืออะไร
Vehicle คือ Entity ประเภทรถ
เช่น
Car
Motorcycle
Truck
Helicopter
Plane
Boat
ตัวอย่างหา Vehicle ที่ Player อยู่
local ped =
PlayerPedId()
local vehicle =
GetVehiclePedIsIn(
ped,
false
)
ค่า vehicle คือ Vehicle Entity Handle ใน Context นั้น
④ Object Entity คืออะไร
Object คือ Entity ประเภทสิ่งของหรือ Prop
ตัวอย่างเช่น
กล่อง
โต๊ะ
เก้าอี้
ป้าย
Barrier
Mission Prop
Script สามารถสร้าง Object แล้วจัดการ
Position
Rotation
Network State
Visibility
Attachment
ตาม Native และ Architecture ที่ใช้
⑤ Entity Handle คืออะไร
Entity Handle คือค่าที่ Script ใช้อ้างถึง Internal Game Representation ของ Entity ใน Context ปัจจุบัน
เช่น
local ped =
PlayerPedId()
ค่า ped คือ Handle
หรือ
local vehicle =
GetVehiclePedIsIn(
ped,
false
)
ค่า vehicle ก็คือ Handle
จากนั้นสามารถส่ง Handle นี้ให้ Native อื่น
GetEntityCoords(vehicle)
⑥ Entity Handle เป็น ID ถาวรหรือไม่
ไม่
Entity Handle ไม่ควรถูกใช้เป็น Persistent ID ของรถหรือ Player
Cfx.re ระบุว่า Entity Handle เป็น Local Handle และ Entity เดียวกันสามารถมี Handle ต่างกันในแต่ละ Client ได้
ดังนั้นอย่าเก็บ
vehicleHandle = 123
ลง Database แล้วคิดว่า Server Restart หรือ Player คนอื่นจะใช้ 123 อ้างถึงรถคันเดิมได้
Entity Handle ไม่ได้ถูกออกแบบมาเพื่อสิ่งนั้น
⑦ Entity Handle เหมือนกันทุก Client ไหม
ไม่
สมมติรถคันเดียวกันอยู่ใน Scope ของ Player A และ Player B
อาจเกิด
Client A
Vehicle Handle = 125
Client B
Vehicle Handle = 386
ทั้งสอง Handle สามารถอ้างถึงรถ Networked Entity คันเดียวกันในแต่ละเครื่องได้
ดังนั้น
Entity Handle
=
Local Reference
ไม่ใช่ Global Multiplayer ID
⑧ ถ้าต้องอ้าง Entity ข้าม Client ใช้อะไร
ใช้ Network ID
แนวคิดคือ
Client A
Entity Handle
↓
Network ID
↓
Network
↓
Client B
↓
Entity Handle ของ Client B
FiveM มี Native สำหรับแปลงระหว่าง Entity Handle กับ Network ID
เช่น
NetworkGetNetworkIdFromEntity(
entity
)
และ
NetworkGetEntityFromNetworkId(
netId
)
⑨ Entity Handle กับ Network ID ต่างกันอย่างไร
จำง่าย ๆ
Entity Handle
→ Local Reference
Network ID
→ Network Reference
ถ้า Logic อยู่ Client เดียว
Entity Handle
มักเพียงพอ
ถ้าต้องส่ง Entity ไปอีก Client หรือ Server
Network ID
มักเป็น Identifier ที่เหมาะกว่า
⑩ ตัวอย่าง Entity Handle → Network ID
local vehicle =
GetVehiclePedIsIn(
PlayerPedId(),
false
)
if DoesEntityExist(vehicle) then
local netId =
NetworkGetNetworkIdFromEntity(
vehicle
)
print(
'Network ID:',
netId
)
end
ตอนนี้ netId สามารถใช้เป็น Network Reference ตามระบบที่เหมาะสม
⑪ Network ID → Entity Handle
อีก Client สามารถรับ Network ID แล้วแปลง
local entity =
NetworkGetEntityFromNetworkId(
netId
)
สำหรับ Vehicle ยังมี Alias อย่าง
NetToVeh(netId)
Ped ก็มี API ที่เกี่ยวข้องตามประเภท Entity
แต่ต้องตรวจก่อนว่า Entity อยู่ใน Scope และมีอยู่จริง
⑫ Network ID เป็น Persistent ID หรือไม่
ไม่
Cfx.re ระบุว่า Entity Network ID เป็น Integer แบบ 16-bit ที่สามารถถูกนำกลับมาใช้ใหม่หลัง Entity เดิมหมดอายุ
ดังนั้น Network ID ควรใช้
ระหว่าง Lifetime ของ Entity
ไม่ควรบันทึกลง Database เพื่อเป็น Permanent Vehicle Identifier
รถถาวรควรใช้ข้อมูลอย่าง
Database ID
Plate
UUID
Framework Vehicle ID
ตาม Architecture
⑬ Entity อยู่ใน Scope คืออะไร
ใน Multiplayer Client ไม่จำเป็นต้องมี Entity ทุกตัวใน Server อยู่ในเครื่องตลอดเวลา
OneSync ใช้ระบบ Scope/Culling เพื่อส่ง Entity ที่เกี่ยวข้องให้ Client
แนวคิดคือ
Entity อยู่ใกล้ / อยู่ใน Scope
→ Client มี Entity
Entity อยู่นอก Scope
→ Client อาจไม่มี Entity Local
นี่ช่วยลด Network และ Processing Load
⑭ ทำไมมี Network ID แต่หา Entity ไม่เจอ
เพราะ Entity อาจไม่ได้อยู่ใน Scope ของ Client นั้น
Cfx.re ระบุว่า Network ID หนึ่งไม่ได้หมายความว่า Entity นั้นต้องมีอยู่ใน Client ทุกคนเสมอ
ดังนั้นก่อนใช้ Network ID ควรตรวจ
NetworkDoesEntityExistWithNetworkId(
netId
)
ตาม Use Case
อย่าคิดว่า
มี Net ID
=
มี Entity Handle แน่นอน
⑮ DoesEntityExist คืออะไร
DoesEntityExist() ใช้ตรวจว่า Entity Handle มี Entity ที่ Valid อยู่หรือไม่
ตัวอย่าง
if DoesEntityExist(vehicle) then
print('Vehicle exists')
end
เหมาะก่อนทำ Action กับ Entity ที่อาจถูกลบหรือหายไปแล้ว
⑯ ทำไมต้องตรวจ DoesEntityExist
สมมติ Script เก็บ
local vehicle =
someVehicle
หลังจากนั้นรถอาจถูก
Delete
Despawn
Resource Cleanup
Mission Cleanup
Network Scope Change ในบาง Context
ถ้า Code ภายหลังยังใช้ Handle โดยไม่ตรวจ อาจเกิด Behavior ที่ไม่ถูกต้อง
Pattern ที่ปลอดภัยกว่า
if not DoesEntityExist(vehicle) then
return
end
⑰ Entity Handle ไม่ใช่ Player Server ID
นี่เป็น Error ที่มือใหม่เจอบ่อย
ตัวอย่าง
local ped =
PlayerPedId()
ped ไม่ใช่ Server ID ของ Player
ถ้าต้องการ Server ID ฝั่ง Client ใช้ API ที่เกี่ยวข้อง เช่นแปลง Player Index เป็น Server ID
จึงต้องแยก
Ped Handle
Player Index
Server ID
Network ID
ให้ถูกต้อง
⑱ Player Ped เป็น Networked Entity ไหม
โดยปกติ Player จะมี Ped ที่เป็น Networked Entity
Cfx.re ระบุว่า Player Ped เป็น Standard Network Object และมี Network ID
ดังนั้น Player มีทั้ง Concept
Player
+
Ped Entity
ซึ่งไม่ใช่สิ่งเดียวกัน
⑲ Player กับ Ped ต่างกันอย่างไร
Player คือ Player Identity/Connection ใน Game Context
Ped คือ Physical Character Entity
ตัวอย่าง Client
Player
→ Player Index
Ped
→ Entity Handle
Server มักใช้
source
เป็น Player Server ID
แล้วสามารถหา Player Ped ผ่าน Native ที่รองรับ
จึงไม่ควรใช้คำว่า Player ID, Ped ID และ Entity ID แทนกันโดยไม่แยกความหมาย
⑳ วิธีหา Player Ped ฝั่ง Server
เมื่อ Server มี Player Source
local src =
source
สามารถหา Ped ตาม Server-side API ที่รองรับ
local ped =
GetPlayerPed(src)
จากนั้น
local coords =
GetEntityCoords(ped)
สามารถใช้กับ OneSync/State Awareness ที่เหมาะสม
มีประโยชน์มากสำหรับ Server-side Position Validation
㉑ Entity Coordinates คืออะไร
Entity มีตำแหน่งในโลก
สามารถหาได้ด้วย
local coords =
GetEntityCoords(entity)
ค่าที่ได้เป็น Coordinates เช่น
x
y
z
Use Case เช่น
Distance Check
Garage
Shop
Mission
Teleport
Zone Validation
㉒ Entity Heading คืออะไร
Heading คือทิศทางที่ Entity หัน
สามารถอ่านด้วย
local heading =
GetEntityHeading(entity)
ใช้กับ
Spawn Vehicle
Spawn Ped
Teleport
Placement
Garage
เช่น Spawn Vehicle ให้หันตามจุดจอด
㉓ Entity Model คืออะไร
Entity แต่ละตัวมี Model
เช่น Vehicle Model
sultan
adder
blista
Ped หรือ Object ก็มี Model ของตัวเอง
Script มักใช้ Model Hash ในการสร้าง Entity
เช่น
local model =
joaat('sultan')
จากนั้น Request Model ก่อนสร้าง Client-side Entityตาม Workflow
㉔ Local Entity คืออะไร
Local Entity คือ Entity ที่ถูกสร้างหรือใช้เฉพาะ Client Context โดยไม่ได้ Network ไปให้ผู้เล่นอื่น
ตัวอย่าง Use Case
Preview Vehicle
Client-only Prop
Temporary Visual
Local Effect
ผู้เล่นอื่นไม่จำเป็นต้องเห็น Entity นั้น
จึงไม่ต้องทำทุก Entity ให้เป็น Networked Entity
㉕ Networked Entity คืออะไร
Networked Entity คือ Entity ที่ถูก Sync ผ่าน Network Layer
เช่นรถที่ผู้เล่นหลายคนต้องเห็นคันเดียวกัน
Concept
Entity
↓
Network ID
↓
OneSync / Network Layer
↓
Relevant Clients
Networked Entity มีเรื่องเพิ่มเติม เช่น
Network ID
Ownership
Scope
Migration
State
Persistence
㉖ Local Entity กับ Networked Entity เลือกอะไร
ถามก่อนว่า
ผู้เล่นคนอื่นต้องเห็นหรือโต้ตอบกับ Entity นี้ไหม?
ถ้าไม่
Local Entity
อาจเหมาะกว่า
ถ้าต้อง Sync ระหว่างผู้เล่น
Networked Entity
จึงเหมาะ
อย่าทำ Prop ตกแต่งชั่วคราวทุกชิ้นเป็น Networked Entity โดยไม่มีเหตุผล
㉗ Entity Ownership คืออะไร
Networked Entity ต้องมี Concept ว่า Client/Server ใดมี Network Control หรือ Ownership ตามระบบ
Ownership มีผลกับ
Physics
Movement
Native Actions
Sync
Migration
ใน OneSync Ownership สามารถเปลี่ยนเมื่อ Entity เข้า/ออก Scope หรือมีการ Migration
ดังนั้นอย่าสมมติว่า Client ที่สร้าง Entity จะเป็น Owner ตลอดไป
หัวข้อนี้จะลงรายละเอียดในบทความ 431
㉘ Entity Ownership กับ Script Ownership เหมือนกันไหม
ไม่ควรใช้คำสองอย่างนี้ปนกัน
Network Ownership เกี่ยวกับการ Sync/Control Entity ใน Network
Script Ownership เกี่ยวข้องกับ Resource/Script Lifecycle และ Mission Entity Behavior ในบางระบบ
เมื่อทำระบบ Entity ขั้นสูงต้องดู Documentation ของ Native และ OneSync ให้ตรงกับสิ่งที่ต้องการจริง ๆ
㉙ Entity Migration คืออะไร
เมื่อ Network Ownership เปลี่ยนจาก Client หนึ่งไปอีก Client หนึ่ง เรียกว่า Ownership Migration ในแนวคิด Networking
ตัวอย่าง
Client A อยู่ใกล้รถ
→ A Control
A ออกนอก Scope
↓
Entity Ownership เปลี่ยน
↓
Client B อาจ Control
ดังนั้น Architecture ไม่ควรผูก Entity Logic สำคัญกับ Owner Client คนเดิมตลอดเวลา
㉚ OneSync เกี่ยวข้องกับ Entity อย่างไร
OneSync เป็นระบบ Synchronization ของ FiveM ที่จัดการ Networked Entities และ Player State ใน Multiplayer
ช่วยเรื่อง
Server-side Entity State
Entity Scope
Ownership
Culling
Server-created Entities
State Bags
Routing Buckets
Entity Development ใน FiveM Server ปัจจุบันจึงสัมพันธ์กับ OneSync อย่างมาก
㉛ Culling คืออะไร
Culling คือการไม่ส่งหรือไม่สร้าง Entity ที่ไม่จำเป็นบน Client ที่อยู่นอกขอบเขตความสนใจ
ตัวอย่าง
Player กรุงเทพจำลอง
ไม่จำเป็นต้องมี Entity ทุกตัวของผู้เล่นที่อยู่อีกด้านของแผนที่อยู่ใน Client Memory/Sync Context พร้อมกัน
OneSync ใช้ Scope เพื่อช่วยลดข้อมูลที่ไม่จำเป็น
㉜ Entity ออกจาก Scope เกิดอะไรขึ้น
Client อาจไม่มี Local Representation ของ Entity นั้นอีก
ดังนั้น Handle บางอย่างไม่ควรถูกถือว่า Valid ตลอดไปเมื่อใช้ในระบบ Networked Entity
ถ้าต้องอ้าง Entity ข้าม Scope/Client ให้ใช้ Network Architecture ที่เหมาะสม
และตรวจ Entity Existence ก่อนใช้งาน
㉝ Network ID เปลี่ยนตอน Ownership Migration ไหม
Cfx.re ระบุว่า Network ID จะไม่เปลี่ยนตลอด Lifetime ของ Network Entity นั้น
แม้ Ownership จะสามารถ Migration ได้
ดังนั้น Network ID เหมาะกว่า Entity Handle สำหรับอ้าง Entity ข้ามเครื่องในช่วง Lifetime เดียวกัน
แต่หลัง Entity ถูกลบ Network ID สามารถถูกนำกลับมาใช้กับ Entity อื่นในอนาคตได้
㉞ Entity Handle เปลี่ยนได้ไหม
ได้
Cfx.re ระบุว่า Entity เดียวกันหากถูก Recreated Locally หรือ Remotely สามารถได้รับ Handle ใหม่ได้
ดังนั้น Script ที่เก็บ Handle ระยะยาวควรตรวจ Validity และ Lifecycle
อย่าพึ่ง Number ของ Handle เป็น Identity ถาวร
㉟ วิธีส่งรถจาก Client ไป Server
ไม่ควรส่ง Local Entity Handle แล้วสมมติ Server จะตีความเป็น Entity เดียวกันเสมอ
Pattern ที่เหมาะกว่าใน Network Use Case คือ
Client
local vehicle =
GetVehiclePedIsIn(
PlayerPedId(),
false
)
if not DoesEntityExist(vehicle) then
return
end
local netId =
NetworkGetNetworkIdFromEntity(
vehicle
)
TriggerServerEvent(
'garage:store',
netId
)
จากนั้น Server ตรวจ Entity ตาม Network ID/Server API ที่เหมาะสม
㊱ ส่ง Entity Handle ไป Client คนอื่นดีไหม
ไม่
เพราะ Handle ของ Client A ไม่จำเป็นต้องตรงกับ Handle ของ Client B
ควรส่ง
Network ID
ตัวอย่าง
TriggerClientEvent(
'vehicle:update',
target,
netId
)
Client เป้าหมายจึง Resolve Network ID เป็น Local Entity Handle ของตัวเอง
㊲ ตัวอย่าง Server → Client Vehicle Network ID
Server
TriggerClientEvent(
'vehicle:highlight',
target,
netId
)
Client
RegisterNetEvent(
'vehicle:highlight',
function(netId)
if not NetworkDoesEntityExistWithNetworkId(
netId
) then
return
end
local vehicle =
NetToVeh(netId)
if not DoesEntityExist(vehicle) then
return
end
-- vehicle logic
end
)
นี่เป็น Pattern ที่เข้าใจ Local Handle กับ Network ID ถูกต้องกว่า
㊳ Server-created Entity คืออะไร
OneSync รองรับการสร้าง Entity บางประเภทจาก Server
เช่น
Vehicle
Ped
Object
ตาม Native/API ที่รองรับ
Cfx.re แนะนำ Server-created Entities เป็น Best Practice สำหรับหลายระบบที่ Server ต้องการควบคุม Entity อย่างเป็น Authority
㊴ ทำไม Server-created Entity น่าสนใจ
เพราะช่วยให้ Server เป็นผู้ควบคุมการสร้าง Entity มากขึ้น
ตัวอย่าง Mission Vehicle
แทน
Client:
Spawn Vehicle เอง
↓
บอก Server ว่าสร้างแล้ว
สามารถออกแบบ
Server:
Validate Request
↓
Create Entity
↓
กำหนด State
↓
Clients รับ Sync
ช่วยลด Client Authority ในระบบสำคัญ
㊵ ตัวอย่าง Server-side Create Vehicle
Cfx.re ยกตัวอย่าง OneSync ด้วย
local vehicle =
CreateVehicleServerSetter(
GetHashKey('blista'),
'automobile',
2204.795,
-887.9213,
1461.224,
90.0
)
จากนั้นสามารถจัด Persistence/Orphan Mode ตาม Requirement
Server-created Entity เหมาะกับระบบที่ Server ต้องเป็นผู้ Author Entity
㊶ SetEntityOrphanMode คืออะไร
สำหรับ Server-created Entity สามารถใช้ Orphan Mode ตาม OneSync API เพื่อควบคุมพฤติกรรมเมื่อ Entity ไม่มี Client Owner
Cfx.re แนะนำ KeepEntity Mode สำหรับกรณีที่ต้องการให้ Server ไม่ลบ Entity เพราะไม่มี Owner
ตัวอย่าง
SetEntityOrphanMode(
vehicle,
2
)
แต่ Entity Persistence จริงยังต้องออกแบบ Lifecycle และ Cleanup ให้ครบ
㊷ Persistent Entity ไม่ใช่ Database Persistence
คำว่า Persistent ใน Entity Networking ไม่ได้แปลว่า Entity จะอยู่ข้าม Server Restart โดยอัตโนมัติ
ถ้าต้องการรถกลับมาหลัง Restart ต้องเก็บข้อมูลใน Persistent Storage เช่น Database
แล้วสร้าง Entity ใหม่เมื่อ Server เริ่มหรือเมื่อจำเป็น
แยก
Runtime Entity Persistence
กับ
Database Persistence
ให้ออกจากกัน
㊸ Entity Cleanup สำคัญไหม
สำคัญมาก
ถ้า Script สร้าง
Vehicles
Peds
Objects
จำนวนมากแต่ไม่ Cleanup อาจเกิด
Entity สะสม
Network Load
Memory Usage
World Clutter
Performance ลดลง
Resource ควรมี Lifecycle ชัดเจนว่า Entity ถูกสร้างเมื่อไรและลบเมื่อไร
㊹ Temporary Entity ควรลบเมื่อไร
ตัวอย่าง Mission Prop
Mission Start
↓
Create Prop
↓
Mission Running
↓
Mission Complete / Cancel
↓
Delete Entity
ไม่ควรปล่อย Prop อยู่ตลอดหลัง Mission จบ
ยกเว้น Entity นั้นตั้งใจเป็น Persistent World Entity
㊺ DeleteEntity ใช้ทำอะไร
ใช้ลบ Entity ที่ Script มีสิทธิ์จัดการตาม Context
ตัวอย่าง
if DoesEntityExist(entity) then
DeleteEntity(entity)
end
แต่กับ Networked Entity ต้องคิดเรื่อง
Ownership
Network Control
Server Authority
Persistence
ด้วย
ไม่ควร Delete Network Entity จาก Clientโดยไม่ออกแบบสิทธิ์ให้เหมาะสม
㊻ Entity Security สำคัญอย่างไร
Client สามารถพยายามสร้างหรือจัดการ Entity ในบางระบบได้
Cfx.re มี OneSync Entity Lockdown เพื่อจำกัด Client-created Entities ตาม Routing Bucket
มี Mode เช่น
strict
relaxed
inactive
และในบางบริบทมี Mode เพิ่มเติมตาม Server/Game Version
ใช้เมื่อ Server ต้องการควบคุม Entity Creation อย่างเข้มงวด
㊼ Entity Lockdown แบบ strict คืออะไร
OneSync Documentation ระบุว่า
strict
จะไม่อนุญาตให้ Client สร้าง Entity ใน Routing Bucket นั้น
แนวคิดคือ
Client
→ ขอ Spawn
Server
→ Validate
Server
→ Create Entity
เหมาะกับระบบที่ต้องการ Server-authoritative Entity Creation
รายละเอียดจะลงลึกในหัวข้อ 440
㊽ Routing Bucket กับ Entity
Routing Bucket ใช้แยก Player และ Entity ออกเป็น Instance/Dimension
ตัวอย่าง
Bucket 0
→ Main World
Bucket 10
→ Mission A
Bucket 20
→ Character Selection
Entity ที่อยู่ Bucket หนึ่งจะถูกจัดการตาม Routing Policy ของ Bucket นั้น
จึงมีประโยชน์กับ Instance System
㊾ Entity อยู่ Bucket ไหนตรวจได้ไหม
FiveM มี Routing Bucket API สำหรับ Server-side Entity/Player
ใช้ตรวจหรือกำหนดว่า Entity อยู่ Bucket ไหน
ระบบ Instance ที่ดีต้องจัด Player และ Entity ให้สัมพันธ์กัน
เช่น Mission Vehicle ควรอยู่ Bucket เดียวกับ Mission Players ตาม Architecture
㊿ State Bag กับ Entity คืออะไร
Network Entity สามารถมี State Bag
ใช้เก็บ State ที่สามารถ Replicate ตาม Policy ของ FiveM
ตัวอย่าง Concept
Vehicle
├── fuel
├── locked
└── customState
แทนการ Broadcast Event ซ้ำทุกครั้งสำหรับข้อมูล State บางประเภท
State Bags จะลงรายละเอียดในหัวข้อ 432
51 Entity State กับ Event ต่างกันอย่างไร
Event เหมาะกับ
Something happened
เช่น
door opened
explosion happened
mission completed
State เหมาะกับ
Something currently is
เช่น
locked = true
fuel = 75
duty = true
Entity State Bags จึงเหมาะกับข้อมูลสถานะบางชนิด
52 Entity กับ ESX เกี่ยวข้องอย่างไร
ESX จัดการ Framework State เช่น
Player Data
Job
Economy
แต่เมื่อ Resource ต้องจัด
Ped
Vehicle
Object
Position
ก็ยังใช้ FiveM/GTA Entity และ Native ตามปกติ
Framework ไม่ได้แทน Entity System
53 Entity กับ QBCore เกี่ยวข้องอย่างไร
เหมือนกัน
QBCore สามารถมี Vehicle/Player APIs ของตัวเอง
แต่ Vehicle ในโลก FiveM ยังเป็น Entity
จึงยังต้องเข้าใจ
Entity Handle
Network ID
Ownership
Scope
เพื่อ Debug Multiplayer Script ได้อย่างถูกต้อง
54 Entity กับ Qbox เกี่ยวข้องอย่างไร
Qbox/ox ecosystem สามารถช่วยเรื่อง Framework และ Library Layer
แต่ Core Multiplayer Entity ยังเป็น FiveM Entity System
ดังนั้น Developer ที่เข้าใจ Entity Core จะสามารถอ่านและแก้ Script ได้ดีขึ้น ไม่ว่าจะใช้ Framework ใด
55 Entity Handle เก็บใน Global Variable ได้ไหม
ได้ถ้าเข้าใจ Lifecycle
เช่น
local missionVehicle = nil
ตอนสร้าง
missionVehicle =
vehicle
ตอนใช้
if missionVehicle
and DoesEntityExist(
missionVehicle
) then
-- logic
end
ตอน Mission จบควร Reset/Cleanup
missionVehicle = nil
อย่าถือว่า Handle เก่าจะ Valid ตลอด Resource Lifetime
56 Entity Handle เก็บใน Database ได้ไหม
ไม่ควร
เช่นไม่ควรบันทึก
entity_handle = 425
เป็น Identity ของรถถาวร
เพราะ Entity Handle เป็น Runtime-local Reference
ควรใช้ Persistent Identifier เช่น
vehicle_id
plate
uuid
owner_id
model
แล้วสร้าง/ค้น Runtime Entity เมื่อจำเป็น
57 Network ID เก็บใน Database ได้ไหม
ไม่ควรใช้เป็น Permanent Identity เช่นกัน
Network ID มีประโยชน์ใน Lifetime ของ Entity
แต่สามารถถูก Reuse หลัง Entity ถูกลบ
Database ควรเก็บ Persistent Identifier ที่ระบบของคุณควบคุมเอง
58 Entity Debug อย่างไร
เริ่มจากตรวจ Handle
local vehicle =
GetVehiclePedIsIn(
PlayerPedId(),
false
)
print(
'handle:',
vehicle
)
ตรวจ Exist
print(
'exists:',
DoesEntityExist(vehicle)
)
หา Network ID
if DoesEntityExist(vehicle) then
local netId =
NetworkGetNetworkIdFromEntity(
vehicle
)
print(
'netId:',
netId
)
end
ช่วยแยกปัญหาว่าอยู่ที่ Handle หรือ Networking
59 Checklist ก่อนจัดการ FiveM Entity
ก่อนเขียนระบบ Entity ให้ถาม
① Entity เป็น Ped, Vehicle หรือ Object?
② Entity เป็น Local หรือ Networked?
③ Handle นี้อยู่ Client ไหน?
④ ต้องส่ง Entity ข้าม Client/Server หรือไม่?
⑤ ถ้าต้องส่ง ใช้ Network ID หรือยัง?
⑥ Entity อยู่ใน Scope หรือไม่?
⑦ ตรวจ DoesEntityExist หรือยัง?
⑧ Network ID ยัง Valid หรือไม่?
⑨ Entity Owner คือใคร?
⑩ Ownership สามารถ Migration ได้หรือไม่?
⑪ Entity ถูกสร้าง Client หรือ Server?
⑫ ต้อง Persistent ใน Runtime หรือไม่?
⑬ ต้องเก็บ Database หรือไม่?
⑭ ต้อง Cleanup เมื่อไร?
⑮ Entity อยู่ Routing Bucket ไหน?
⑯ ต้องมี State Bag หรือไม่?
⑰ Client มีสิทธิ์สร้าง Entity นี้หรือไม่?
⑱ ต้องใช้ Entity Lockdown หรือไม่?
หากตอบคำถามเหล่านี้ได้ Entity System จะมีปัญหาน้อยลงมาก
⑥⓪ หลักจำ FiveM Entity แบบง่ายที่สุด
จำโครงสร้างนี้
Ped
Vehicle
Object
↓
ทั้งหมดเป็น Entity
และ
Entity Handle
=
Local Reference
ถ้าต้องข้าม Network
Entity Handle
↓
Network ID
↓
อีก Client / Server
↓
Local Entity Handle
สุดท้าย
Network ID
≠
Permanent Database ID
นี่คือพื้นฐานสำคัญที่สุดก่อนเข้าสู่ FiveM Networking ขั้นต่อไป
ตัวอย่าง Entity + Network ID แบบสมบูรณ์
client.lua
RegisterCommand(
'myvehicle',
function()
local ped =
PlayerPedId()
local vehicle =
GetVehiclePedIsIn(
ped,
false
)
if not DoesEntityExist(
vehicle
) then
print(
'No vehicle'
)
return
end
local coords =
GetEntityCoords(
vehicle
)
local heading =
GetEntityHeading(
vehicle
)
local netId =
NetworkGetNetworkIdFromEntity(
vehicle
)
print(
'Handle:',
vehicle
)
print(
'Network ID:',
netId
)
print(
'Coords:',
coords
)
print(
'Heading:',
heading
)
end,
false
)
จาก Code นี้จะเห็นว่า Vehicle หนึ่งคันสามารถมีข้อมูลหลายแบบ
Vehicle Entity
↓
Handle
↓
Coordinates
↓
Heading
↓
Network ID
แต่แต่ละค่ามีหน้าที่ต่างกัน
คำถามที่พบบ่อยเกี่ยวกับ FiveM Entity
FiveM Entity คืออะไร
คือ Game Object ที่ Script สามารถอ้างอิงและจัดการได้ เช่น Ped, Vehicle และ Object
Ped เป็น Entity ไหม
เป็น
Vehicle เป็น Entity ไหม
เป็น
Object เป็น Entity ไหม
เป็น
Entity Handle คืออะไร
คือ Local Runtime Handle ที่ใช้อ้างถึง Internal Game Entity ใน Context ปัจจุบัน
Entity Handle เหมือนกันทุก Client ไหม
ไม่ Entity เดียวกันสามารถมี Handle ต่างกันใน Client แต่ละคนได้
Entity Handle เก็บใน Database ได้ไหม
ไม่ควร เพราะไม่ได้เป็น Persistent Identifier
Network ID คืออะไร
คือ Identifier สำหรับอ้าง Networked Entity ข้ามเครื่องในช่วง Lifetime ของ Entity
Network ID เหมือน Entity Handle ไหม
ไม่
Network ID เก็บใน Database เป็น ID ถาวรได้ไหม
ไม่ควร เพราะ Network ID สามารถถูก Reuse หลัง Entity หมด Lifetime
วิธีแปลง Entity เป็น Network ID
ใช้ Native เช่น
NetworkGetNetworkIdFromEntity(
entity
)
วิธีแปลง Network ID เป็น Entity
ใช้
NetworkGetEntityFromNetworkId(
netId
)
หรือ Alias ตามประเภท Entity เช่น NetToVeh()
ทำไมมี Network ID แต่ Client หา Entity ไม่เจอ
เพราะ Entity อาจไม่ได้อยู่ใน Scope ของ Client นั้น
ตรวจ Entity มีอยู่ไหม
ใช้
DoesEntityExist(entity)
Player Ped เป็น Entity ไหม
เป็น Ped Entity และ Player Ped โดยปกติเป็น Networked Entity
source เป็น Entity ไหม
ไม่ source ฝั่ง Server เป็น Player Server ID ไม่ใช่ Entity Handle
OneSync เกี่ยวกับ Entity ไหม
เกี่ยวโดยตรงกับ Entity Synchronization, Scope, Ownership, Server-created Entities, State และ Routing
Server สร้าง Entity ได้ไหม
OneSync รองรับ Server-created Ped, Vehicle และ Object ใน Use Case ที่ Native/API รองรับ
Entity Ownership คืออะไร
คือแนวคิดเกี่ยวกับผู้ที่ควบคุม Networked Entity ใน Network Layer ซึ่งสามารถ Migration ได้ตาม Scope และระบบ OneSync
Entity Lockdown คืออะไร
เป็นระบบ OneSync สำหรับจำกัดการสร้าง Entity จาก Client ตาม Routing Bucket และ Lockdown Mode
สรุป FiveM Entity คืออะไร
FiveM Entity คือสิ่งที่มีตัวตนอยู่ในโลกเกม เช่น Ped, Vehicle และ Object ซึ่ง Script สามารถอ้างอิงและจัดการผ่าน Entity Handle และ Native ต่าง ๆ
โครงสร้างพื้นฐานคือ
Entity
├── Ped
├── Vehicle
└── Object
ตัวอย่าง
local ped =
PlayerPedId()
local coords =
GetEntityCoords(ped)
แต่เมื่อเข้าสู่ Multiplayer ต้องเข้าใจความแตกต่างระหว่าง
Entity Handle
กับ
Network ID
โดย
Entity Handle
→ Local ต่อ Client/Runtime Context
ส่วน
Network ID
→ ใช้อ้าง Networked Entity ข้ามเครื่อง
Entity เดียวกันสามารถมี Handle คนละเลขใน Client แต่ละคนได้ ดังนั้นหาก Client A ต้องบอกรถคันหนึ่งให้ Client B หรือ Server รู้จัก ไม่ควรส่ง Local Handle ไปเป็น Global Identity แต่ควรใช้ Network ID ตาม Networking Architecture
อย่างไรก็ตาม Network ID ก็ไม่ใช่ Database ID ถาวร เพราะสามารถถูกนำกลับมาใช้ใหม่หลัง Entity เดิมถูกลบได้
เมื่อใช้ OneSync ยังต้องเข้าใจเรื่อง
Scope
Culling
Ownership
Migration
Server-created Entity
State Bags
Routing Buckets
Entity Lockdown
เพิ่มขึ้นอีก
สำหรับคนที่เรียน FiveM Developer กับ comsiam จุดที่สำคัญที่สุดของบทนี้คือ อย่าเรียกตัวเลขทุกอย่างว่า Entity ID เพราะ Player Source, Entity Handle และ Network ID เป็นคนละสิ่งกัน และการสับสนระหว่างสามอย่างนี้เป็นสาเหตุของ Bug ใน Multiplayer Script จำนวนมาก
บทความถัดไปของ comsiam จะเจาะเรื่องนี้ต่อทันทีในหัวข้อ FiveM Network ID คืออะไร ว่า Net ID ถูกสร้างอย่างไร ใช้ข้าม Client/Server อย่างไร ทำไม Entity อาจไม่อยู่ใน Scope และทำไม Network ID จึงไม่ควรถูกใช้เป็น Permanent Database ID
Comments
Post a Comment