FiveM Animation และ Emote Menu คืออะไร ใช้งานอย่างไร

FiveM Animation คือการสั่งให้ Ped หรือตัวละครเล่นท่าทาง เช่น โบกมือ นั่ง กอดอก เต้น ใช้โทรศัพท์ ถือของ ทำงาน ชูมือ หรือ Animation สำหรับระบบ Roleplay ต่าง ๆ ส่วน Emote Menu คือเมนูที่รวบรวม Animation เหล่านี้ไว้ให้ผู้เล่นเลือกใช้งานได้ง่าย โดยไม่ต้องพิมพ์ Animation Dictionary และ Animation Name ด้วยตนเอง

ระบบ Animation ของ GTA V/FiveM มักทำงานด้วยแนวคิดสำคัญคือ

Animation Dictionary
+
Animation Name

จากนั้น Script โหลด Animation Dictionary ด้วย REQUEST_ANIM_DICT รอจน HAS_ANIM_DICT_LOADED เป็นจริง แล้วใช้ TASK_PLAY_ANIM เพื่อสั่ง Ped เล่น Animation ที่ต้องการ.

บทความนี้จาก comsiam จะอธิบายตั้งแต่ Animation Dictionary, Animation Name, Flags, Loop, Scenario, Props, Emote Menu ไปจนถึงวิธีแก้ Animation ไม่เล่น ท่าค้าง หรือ Prop ค้างหลังยกเลิก Emote

① FiveM Animation คืออะไร

Animation คือการเคลื่อนไหวของ Ped ที่ถูกกำหนดไว้ล่วงหน้า เช่น

โบกมือ
กอดอก
เต้น
นั่ง
คุกเข่า
ยกมือ
ใช้โทรศัพท์
กินอาหาร
ดื่มน้ำ
ทำงาน
ตรวจเอกสาร

FiveM สามารถสั่ง Ped เล่น Animation ผ่าน Native เช่น

TASK_PLAY_ANIM

ซึ่งรับ Animation Dictionary และ Animation Name รวมถึงค่าควบคุม Blend, Duration และ Animation Flags.

② Emote คืออะไร

ใน FiveM คำว่า Emote มักใช้เรียก Animation หรือท่าทางที่ผู้เล่นเรียกใช้งานเอง

เช่น

/e wave
/e sit
/e dance
/e crossarms
/e phone

ชื่อ Command เหล่านี้ไม่ใช่ Native มาตรฐานของ GTA โดยตรง แต่เป็นสิ่งที่ Emote Resource หรือ Server Script สร้างขึ้นเพื่อ Map ไปหา Animation ที่ต้องการ

③ Emote Menu คืออะไร

Emote Menu คือ UI หรือ Menu ที่ช่วยให้ผู้เล่นเลือก Animation

โครงสร้างโดยทั่วไปคือ

ผู้เล่นเปิด Emote Menu
↓
เลือก Dance
↓
Script หา Anim Dict + Anim Name
↓
โหลด Dictionary
↓
เล่น Animation

ดังนั้น Emote Menu เป็นเพียง Layer ที่ทำให้ระบบ Animation ใช้งานง่ายขึ้น

④ Animation Dictionary คืออะไร

Animation Dictionary หรือที่มักเรียกสั้น ๆ ว่า

Anim Dict

คือชุด Animation ที่เกมเก็บไว้ภายใต้ชื่อ Dictionary

ตัวอย่างเชิงแนวคิด

Animation Dictionary
├── Animation A
├── Animation B
├── Animation C
└── Animation D

ก่อนใช้งาน Dictionary ควรถูก Request ด้วย REQUEST_ANIM_DICT.

⑤ Animation Name คืออะไร

ภายใน Animation Dictionary จะมี Animation Clips หรือชื่อ Animation ที่ใช้ระบุท่าเฉพาะ

ดังนั้นข้อมูลหนึ่ง Emote อาจประกอบด้วย

Anim Dict
+
Anim Name

ตัวอย่าง

Dictionary = mp_arresting
Animation = idle

Cfx.re เองมีตัวอย่างการโหลด mp_arresting และตรวจด้วย HAS_ANIM_DICT_LOADED ก่อนใช้ Animation.

⑥ Anim Dict กับ Anim Name ต่างกันอย่างไร

จำง่าย ๆ

Anim Dict
= กล่อง Animation

Anim Name
= Animation หนึ่งตัวในกล่องนั้น

หาก Dictionary ถูกแต่ Animation Name ผิด ท่าอาจไม่เล่น

หาก Animation Name ถูกแต่ Dictionary ผิด ก็ไม่สามารถหา Animation นั้นได้เช่นกัน

⑦ ก่อนเล่น Animation ต้อง Request Anim Dict หรือไม่

สำหรับ TASK_PLAY_ANIM ควรโหลด Animation Dictionary ก่อน

ขั้นตอนคือ

REQUEST_ANIM_DICT
↓
HAS_ANIM_DICT_LOADED
↓
TASK_PLAY_ANIM

Cfx.re มี Native สำหรับ Request และตรวจ Loading State โดยตรง.

⑧ ตัวอย่างโหลด Animation Dictionary

local dict = 'mp_arresting'

RequestAnimDict(dict)

while not HasAnimDictLoaded(dict) do
    Wait(0)
end

REQUEST_ANIM_DICT ใช้ Request Dictionary และ HAS_ANIM_DICT_LOADED ใช้ตรวจว่า Dictionary ถูกโหลดพร้อมใช้งานแล้วหรือยัง.

⑨ ทำไม Loop ต้องมี Wait

ไม่ควรเขียน

while not HasAnimDictLoaded(dict) do
end

เพราะ Thread จะวนโดยไม่ Yield

ควรใช้

while not HasAnimDictLoaded(dict) do
    Wait(0)
end

เพื่อให้ Game มีโอกาสประมวลผล Streaming และ Thread อื่น

⑩ ควรมี Timeout ตอนโหลด Animation ไหม

สำหรับ Production Script ควรพิจารณา

ตัวอย่าง

local timeout = GetGameTimer() + 10000

RequestAnimDict(dict)

while not HasAnimDictLoaded(dict) do
    Wait(0)

    if GetGameTimer() > timeout then
        print('Animation dictionary load timeout')
        return
    end
end

ช่วยป้องกัน Script รอ Dictionary ที่ผิดหรือมีปัญหาโดยไม่มีทางออก

⑪ TaskPlayAnim คืออะไร

TASK_PLAY_ANIM เป็น Native หลักสำหรับให้ Ped เล่น Animation

Parameters สำคัญประกอบด้วย

Ped
Animation Dictionary
Animation Name
Blend In Speed
Blend Out Speed
Duration
Flags
Playback Rate
Lock X
Lock Y
Lock Z

ตาม Native Reference ของ Cfx.re.

⑫ ตัวอย่าง TaskPlayAnim

local ped = PlayerPedId()

TaskPlayAnim(
    ped,
    dict,
    anim,
    8.0,
    -8.0,
    -1,
    1,
    0.0,
    false,
    false,
    false
)

ค่าที่เหมาะสมขึ้นอยู่กับ Animation ที่ใช้ โดยเฉพาะ Duration และ Flags.

⑬ Blend In Speed คืออะไร

Blend In คือความเร็วในการเปลี่ยนจากท่าปัจจุบันเข้าสู่ Animation

ค่าต่ำหรือสูงจะทำให้ Transition แตกต่างกัน

ถ้าปรับไม่เหมาะอาจเห็นตัวละคร

เปลี่ยนท่ากระชาก
กระโดดเข้า Animation
Transition ช้าเกิน

TASK_PLAY_ANIM แยก Blend In และ Blend Out ออกจากกัน.

⑭ Blend Out Speed คืออะไร

Blend Out คือการเปลี่ยนจาก Animation กลับสู่ State ปกติ

Animation บางชนิดต้องการให้จบอย่างนุ่มนวล

บางชนิดอาจต้องหยุดเร็ว

จึงไม่ควรใช้ค่าชุดเดียวกับทุก Emote โดยไม่ทดสอบ

⑮ Duration คืออะไร

Duration กำหนดระยะเวลาที่ Task Animation ทำงาน

บาง Emote ต้องการเล่นครั้งเดียว

เช่น

โบกมือ
ทักทาย
ชี้

บาง Emote ต้องการค้างหรือ Loop

เช่น

กอดอก
นั่ง
เต้น
ถือป้าย

Duration จึงควรสัมพันธ์กับ Animation Flags ที่ใช้.

⑯ Animation Flags คืออะไร

Flags ใช้กำหนด Behavior ของ Animation

เช่นว่า

Loop หรือไม่
Hold Last Frame หรือไม่
อนุญาตให้ขยับบางส่วนหรือไม่
Animation มีผลกับร่างกายอย่างไร

Native Reference ของ TASK_PLAY_ANIM ระบุ Animation Flags เป็น Parameter โดยตรง.

⑰ AF_LOOPING คืออะไร

Flag สำหรับ Loop ทำให้ Animation เล่นซ้ำ

เหมาะกับ

Dance
Cross Arms
Idle Pose
บาง Emote ที่ต้องค้าง

แต่ถ้าใช้ Loop กับ Animation ที่ออกแบบให้เล่นครั้งเดียว อาจเห็นการกระตุกทุกครั้งที่ Animation เริ่มใหม่

⑱ Hold Last Frame คืออะไร

Animation บางประเภทต้องการให้ Character ค้างที่ Frame สุดท้าย

เช่น Pose บางแบบ

แต่ไม่ควรใช้กับทุก Animation เพราะอาจทำให้ผู้เล่นดูเหมือนค้างหลัง Animation จบ

⑲ Animation แบบ Full Body คืออะไร

Full-body Animation ใช้ร่างกายส่วนใหญ่หรือทั้งตัว

ตัวอย่าง

นั่ง
นอน
เต้น
คุกเข่า

มักจำกัดการเดินหรือ Action อื่นของ Character มากกว่า Upper-body Animation

⑳ Upper-body Animation คืออะไร

Upper-body Animation เน้นส่วนบนของร่างกาย

ตัวอย่างเช่น

ถือบางอย่าง
Gesture
บาง Phone Animation

สามารถออกแบบให้ผู้เล่นยังเคลื่อนที่ได้ในบางกรณี ขึ้นกับ Flags และ Animation เอง

㉑ ทำไม Emote บางอันเดินได้แต่บางอันเดินไม่ได้

เกิดจากหลายปัจจัย เช่น

Animation Design
Flags
Full-body/Upper-body
Task State

อย่าคิดว่า Animation ที่ดูคล้ายกันจะใช้ Flags ชุดเดียวกันแล้วให้ผลเหมือนกัน

㉒ Animation เล่นแล้วตัวละครเดินไม่ได้

ถ้าเป็น Behavior ที่ไม่ต้องการ ให้ตรวจ

Flags
Task State
Animation Type

ก่อน

บาง Animation ถูกออกแบบให้ล็อก Character อยู่แล้ว

㉓ Animation เล่นแล้วเดินได้ทั้งที่ต้องการให้อยู่กับที่

กรณีตรงข้ามให้ตรวจ Flags และว่ามี Resource อื่น Apply Movement Task เข้ามาพร้อมกันหรือไม่

Emote System ที่ดีควรกำหนด Behavior ของแต่ละ Animation แยกเป็นข้อมูล เช่น

CanMove = true
หรือ
CanMove = false

แล้ว Map ไปยัง Flags ที่เหมาะสม

㉔ Scenario คืออะไร

Scenario เป็นระบบ Task สำเร็จรูปของ GTA ที่ใช้กับ Ped

FiveM มี

TASK_START_SCENARIO_IN_PLACE

สำหรับให้ Ped เริ่ม Scenario ณตำแหน่งปัจจุบัน.

ตัวอย่าง Scenario สามารถเหมาะกับพฤติกรรมอย่าง

ยืนทำงาน
ดื่ม
ทำกิจกรรม
ใช้เครื่องมือ

ขึ้นกับ Scenario ที่ GTA มี

㉕ Scenario ต่างจาก Animation อย่างไร

จำง่าย ๆ

Animation
→ เล่น Animation Clip โดยตรง

Scenario
→ ให้ Ped เข้า Activity/Behavior สำเร็จรูปของ GTA

Scenario อาจจัดการ Animation หรือ Behavior หลายอย่างภายในให้เอง

จึงสะดวกกับ NPC หรือ Activities บางประเภท

㉖ TaskStartScenarioInPlace ใช้อย่างไร

โครงสร้างพื้นฐานคือ

local ped = PlayerPedId()

TaskStartScenarioInPlace(
    ped,
    scenarioName,
    0,
    true
)

Native นี้ทำให้ Ped เริ่ม Scenario ณตำแหน่งปัจจุบัน โดยมี Parameter สำหรับ Scenario Name และ Intro Clip Behavior.

㉗ TaskStartScenarioAtPosition คืออะไร

FiveM ยังมี

TASK_START_SCENARIO_AT_POSITION

ซึ่งสั่ง Ped ให้ไปหรือ Warp ไปยัง Position และ Heading ที่กำหนด แล้วเริ่ม Scenario.

เหมาะกับ NPC ที่ต้องทำกิจกรรมตรงจุดเฉพาะ เช่น

ช่างทำงานที่โต๊ะ
NPC ยืนตรง Counter
Guard ยืนตำแหน่งประจำ

㉘ Scenario กับ Emote Menu ใช้ร่วมกันได้ไหม

ได้

Emote Menu สามารถเก็บข้อมูลได้ทั้ง

Type = Animation

หรือ

Type = Scenario

เมื่อผู้เล่นเลือก Emote ระบบจึงตัดสินใจว่าจะใช้

TASK_PLAY_ANIM

หรือ

TASK_START_SCENARIO_IN_PLACE

ตามประเภทของรายการ

㉙ Emote Menu ที่ดีควรเก็บข้อมูลอะไร

ตัวอย่างโครงสร้าง

{
    name = 'crossarms',
    type = 'animation',
    dict = '...',
    anim = '...',
    flags = 49
}

และสำหรับ Prop Emote อาจมีเพิ่ม

Prop Model
Bone
Position Offset
Rotation Offset

แนวคิดนี้ช่วยให้เพิ่ม Emote ใหม่ได้โดยไม่ต้องเขียน Logic ใหม่ทุกตัว

㉚ Prop Emote คืออะไร

Prop Emote คือ Animation ที่มี Object ประกอบ

เช่น

ดื่มกาแฟ + แก้ว
ใช้โทรศัพท์ + โทรศัพท์
ถือกล่อง + กล่อง
กินอาหาร + อาหาร
ถือป้าย + ป้าย

ระบบทั่วไปคือ

โหลด Animation
↓
สร้าง Object
↓
Attach Object กับ Ped
↓
เล่น Animation

FiveM มี ATTACH_ENTITY_TO_ENTITY สำหรับ Attach Entity เข้ากับ Entity อื่นพร้อม Bone Index และ Position/Rotation Offset.

㉛ Props ใน Emote เป็น Ped Props หรือ Object Props

ส่วนใหญ่ Emote Props เช่น

กาแฟ
โทรศัพท์
กล่อง
อาหาร
ป้าย

เหมาะกับ Object Entity ที่ Attach กับ Ped

ไม่ใช่ Ped Clothing Prop อย่างหมวกหรือแว่น

ต้องแยกสองระบบนี้ออกจากกัน

㉜ Attach Prop กับ Bone อย่างไร

แนวคิดคือ

Create Object
↓
หา Bone ของ Ped
↓
Attach Entity
↓
กำหนด Offset
↓
กำหนด Rotation

ATTACH_ENTITY_TO_ENTITY รองรับ Bone Index และค่าตำแหน่ง/Rotation สำหรับการ Attach.

㉝ ทำไมแก้วกาแฟลอยจากมือ

ส่วนใหญ่เกิดจาก

Bone ผิด
X Offset ผิด
Y Offset ผิด
Z Offset ผิด
Rotation ผิด

ถ้า Object ตาม Character ไปถูกแล้ว แปลว่าการ Attach ทำงาน

เหลือเพียงปรับ Alignment

㉞ ทำไมโทรศัพท์กลับด้าน

แก้ Rotation Offset

Model แต่ละตัวมี Orientation ไม่เหมือนกัน

ค่าที่ใช้กับ

Coffee Cup

จึงไม่สามารถ Copy มาใช้กับ

Phone

แล้วคาดว่าจะตรงมือเสมอไป

㉟ Prop ต้องถูกลบเมื่อหยุด Emote หรือไม่

ถ้า Object ถูกสร้างเฉพาะสำหรับ Emote ควร Cleanup เมื่อ Emote จบ

ตัวอย่าง

Cancel Emote
↓
Stop Animation
↓
Detach/Delete Object
↓
Clear State

มิฉะนั้นจะเกิดปัญหา Prop ค้างหรือ Prop ซ้ำเมื่อเล่น Emote ใหม่

㊱ ทำไม Prop ซ้ำหลายชิ้น

ตัวอย่าง

/e coffee
/e coffee
/e coffee

แล้วมีแก้ว 3 ใบ

สาเหตุคือ Script

Create Object ทุกครั้ง

แต่ไม่ได้

Delete Object เดิม

ก่อนสร้างใหม่

Emote Manager ควรเก็บ Handle ของ Active Prop ไว้และ Cleanup อย่างถูกต้อง

㊲ Animation จบแต่ Prop ยังติดมือ

นี่คือปัญหา Cleanup แยกจาก Animation

การหยุด Animation ไม่ได้แปลว่า Object Entity ที่ Script สร้างจะถูกลบโดยอัตโนมัติ

จึงต้อง Cleanup Prop ใน Emote Resource เอง

㊳ ClearPedTasks คืออะไร

FiveM มี

CLEAR_PED_TASKS

สำหรับ Clear Tasks ของ Ped รวมถึง Animation/Tasks ที่ Scripts สร้างขึ้น.

จึงมักใช้เป็นส่วนหนึ่งของคำสั่ง

Cancel Emote

㊴ ตัวอย่าง Cancel Emote

local ped = PlayerPedId()

ClearPedTasks(ped)

จากนั้นต้อง Cleanup Props หรือ Resource State อื่นเพิ่มเติมตามระบบที่คุณสร้าง เพราะ CLEAR_PED_TASKS มีหน้าที่ Clear Tasks ของ Ped.

㊵ ClearPedTasksImmediately ต่างจาก ClearPedTasks อย่างไร

FiveM มี

CLEAR_PED_TASKS_IMMEDIATELY

สำหรับหยุดสิ่งที่ Ped กำลังทำทันที.

ควรใช้เมื่อจำเป็นจริง เพราะการหยุดแบบ Immediate มี Behavior ต่างจากการ Clear Tasks ปกติ

สำหรับ Emote ทั่วไปควรทดสอบว่า CLEAR_PED_TASKS เพียงพอหรือไม่ก่อน

㊶ StopAnimTask คืออะไร

หากต้องการหยุดเฉพาะ Animation ที่รู้ Dictionary และ Animation Name สามารถใช้

STOP_ANIM_TASK

ซึ่งรับ Ped, Animation Dictionary, Animation Name และ Exit Speed.

มีประโยชน์เมื่อไม่ต้องการ Clear Task อื่นทั้งหมดของ Ped

㊷ StopAnimTask กับ ClearPedTasks ใช้อันไหนดี

StopAnimTask

เหมาะเมื่อรู้ Animation ที่ต้องการหยุดและอยากจำกัดผลกระทบ

ClearPedTasks

เหมาะเมื่อ Emote System ต้องการยกเลิก Current Script Tasks ของ Ped

อย่าใช้ CLEAR_PED_TASKS แบบกว้างทุกครั้งหาก Character กำลังทำ Gameplay Task สำคัญจาก Resource อื่น

㊸ RemoveAnimDict คืออะไร

เมื่อไม่ต้องการ Animation Dictionary ต่อ สามารถใช้

REMOVE_ANIM_DICT

เพื่อ Release Animation Dictionary จากการใช้งานของ Script.

แนวคิดคือ

Request
↓
Use
↓
Remove เมื่อไม่ต้องการ

โดยเฉพาะ Resource ที่โหลด Animation Dictionaries จำนวนมาก

㊹ ต้อง RemoveAnimDict ทันทีหลัง TaskPlayAnim ไหม

ไม่ควรทำแบบเดาโดยไม่ทดสอบ Lifecycle ของ Animation

ควร Release เมื่อ Script ไม่ต้องใช้ Dictionary นั้นต่อแล้ว

หากระบบมี Emote เดียวเล่นซ้ำบ่อย การออกแบบ Cache/Release ต้องสมเหตุสมผล ไม่ใช่ Request/Remove ทุก Frame

㊺ Animation ไม่เล่นทั้งที่ Dictionary โหลดแล้ว

ตรวจ

Animation Name
Ped
TaskPlayAnim ถูกเรียกหรือไม่
Flags
Ped State
Resource Error

ถ้า

HasAnimDictLoaded(dict) = true

แสดงว่า Dictionary Loading ผ่านแล้ว

ไม่ควรกลับไปแก้ Request Loop ก่อนตรวจ Animation Name และ Task

㊻ Animation Name ผิดมีอาการอย่างไร

มักเกิด

Dictionary โหลดผ่าน
แต่ไม่มีท่าที่ต้องการ

หรือไม่มี Animation เล่น

ให้ตรวจคู่ข้อมูล

Dictionary
Animation Name

พร้อมกัน

อย่าแก้เพียง Dictionary อย่างเดียว

㊼ Emote เล่นได้บางอันแต่บางอันไม่ได้

นี่ช่วยแยกปัญหาได้มาก

ถ้า Emote Menu ทำงานและ Animation อื่นเล่นได้

ปัญหาอาจอยู่ที่รายการนั้น เช่น

Anim Dict ผิด
Anim Name ผิด
Scenario Name ผิด
Prop Model ผิด
Flags ผิด

มากกว่าทั้ง Resource

㊽ Emote Menu ไม่เปิดเลย

กรณีนี้ยังไม่ถึง Animation Layer

ตรวจ

Resource Started
Command/Keybind
NUI/Menu
Client Error
Framework Integration

ก่อน

อย่าแก้ TASK_PLAY_ANIM หาก Menu ยังไม่ Trigger Event เลย

㊾ Menu เปิดแต่กด Emote แล้วไม่มีอะไรเกิดขึ้น

ใส่ Debug Log

print('selected emote:', emoteName)
print('dict:', dict)
print('anim:', anim)

จากนั้นตรวจ

Event ถูกเรียก?
Dictionary โหลด?
TaskPlayAnim ถูกเรียก?

วิธีนี้ช่วยแยก UI Problem ออกจาก Animation Problem

㊿ Animation ค้างหลังยกเลิก

ตรวจว่า Cancel Flow ทำครบหรือไม่

Stop/Clear Task
↓
Delete Prop
↓
Clear Animation State
↓
Reset Emote Flags

ถ้า Script มี Boolean เช่น

isEmoting = true

แต่ไม่ได้ Reset อาจทำให้ระบบคิดว่าผู้เล่นยังเล่น Emote อยู่

51. ผู้เล่นกดยกเลิกแล้วเดินไม่ได้

ตรวจ

Animation Flags
Task State
Control Disable Logic
Freeze State
Emote Boolean

โดยเฉพาะ Script ที่ Disable Controls ทุก Frame ขณะ isEmoting == true

ถ้า Animation ถูกหยุดแล้วแต่ Boolean ยังไม่ Reset ผู้เล่นอาจยังถูกล็อก Controls

52. Animation หยุดแล้ว Controls ยังถูกปิด

นี่ไม่ใช่ Animation Asset Problem

ตัวอย่าง

while isEmoting do
    DisableControlAction(...)
end

ถ้า isEmoting ไม่กลับเป็น false Controls จะยังถูกปิด

ต้องแก้ State Management ของ Emote Resource

53. Emote ถูกยกเลิกเมื่อเดินได้ไหม

ขึ้นกับการออกแบบ

บาง Server ต้องการ

เดิน → Cancel Emote

บาง Emote อนุญาตให้เดินได้

ระบบที่ดีควรเก็บ Metadata ของแต่ละ Emote เช่น

CanMove
Loop
Duration
Prop
CancelOnMovement

ไม่ควรใช้ Behavior เดียวกับทุก Animation

54. Emote ควรถูกยกเลิกเมื่อเข้า Vehicle ไหม

สำหรับหลาย Emote ควรพิจารณา

เพราะ Full-body Animation หรือ Attached Props อาจทำให้

ท่านั่งรถผิด
Prop ทะลุรถ
Animation ค้าง

ระบบสามารถตรวจ Vehicle State แล้ว Cleanup Emote ตาม Design

55. Emote ควรถูกยกเลิกเมื่อตายหรือไม่

ควรมี Cleanup Logic สำหรับ

Death
Respawn
Character Change
Resource Stop

โดยเฉพาะ Prop Emotes

มิฉะนั้นอาจเกิด

Prop ค้าง
State isEmoting ค้าง
Animation State ผิด

หลังผู้เล่นเกิดใหม่

56. Emote ตอนถืออาวุธควรอนุญาตไหม

ขึ้นกับ Gameplay

Server Roleplay บางแห่งอาจไม่ต้องการให้ผู้เล่น

ถือปืน
+
เต้น

พร้อมกัน

จึงควรมี Validation ก่อนเล่น Emote เช่น

Dead?
In Vehicle?
Armed?
Handcuffed?
Busy?

ตามกฎของ Server

57. Handcuff Animation ทำงานอย่างไร

Cfx.re มีตัวอย่าง Handcuff ที่ Request Dictionary mp_arresting, รอจนโหลด และตรวจ Animation State ขณะ Ped ถูก Handcuffed.

นี่แสดงให้เห็นว่า Animation มักเป็นเพียงส่วนหนึ่งของ Gameplay State

เช่น Handcuff ยังมี State อื่นที่ Script ต้องจัดการ ไม่ใช่แค่เล่น Animation แล้วจบ

58. Animation กับ Gameplay State ต้องแยกกัน

ตัวอย่าง

Handcuffed
≠
แค่ Animation มือไพล่หลัง

เพราะ Gameplay State อาจต้อง

ปิด Weapon
จำกัด Controls
จำกัด Movement
ป้องกัน Actions
Sync State

ดังนั้นอย่าใช้ Animation เพียงอย่างเดียวเป็น Security Mechanism

59. Animation Synchronization ระหว่างผู้เล่นทำอย่างไร

สำหรับ Emote ธรรมดาของ Player Ped การเคลื่อนไหวของ Networked Player Ped จะเกี่ยวข้องกับ Networked Entity State ของ GTA/FiveM

แต่ Animation ที่ต้อง Sync หลาย Entities อย่างแม่น เช่น

ผู้เล่นสองคนทำ Action ร่วมกัน
Ped + Object
Cutscene-like Scene

อาจต้องใช้ระบบที่ซับซ้อนกว่า Task Animation ธรรมดา

FiveM มี Natives สำหรับ Network Synchronised Scenes และ Ped Animations โดยเฉพาะ.

60. Shared Emote เช่นกอดกันยากกว่า Emote ปกติไหม

ใช่

เพราะต้องจัดการอย่างน้อย

Player A Position
Player B Position
Heading
Animation Timing
Network
Cancel
Distance

ถ้าใช้เพียง

TaskPlayAnim A
TaskPlayAnim B

แยกกัน Timing และตำแหน่งอาจไม่ตรง

61. Network Synchronised Scene คืออะไร

FiveM/GTA มีระบบ Synchronised Scene สำหรับจัด Animation หลาย Entities ให้ทำงานสัมพันธ์กัน และมี Native สำหรับเพิ่ม Ped เข้า Network Synchronised Scene โดยระบุ Animation Dictionary และ Animation Name.

เหมาะกับระบบที่ต้องการ Coordination มากกว่า Emote คนเดียว

62. Emote Menu ต้องใช้ ESX ไหม

ไม่

Animation Natives เช่น

REQUEST_ANIM_DICT
TASK_PLAY_ANIM
CLEAR_PED_TASKS

เป็น GTA/FiveM APIs.

ESX อาจใช้สำหรับ

Permissions
Jobs
Items
Commands
Player State

แต่ Animation Engine ไม่ได้ขึ้นกับ ESX

63. Emote Menu ต้องใช้ QBCore ไหม

ไม่จำเป็นเช่นกัน

Standalone Emote Resource สามารถเรียก FiveM Natives โดยตรงได้

Framework จะสำคัญเมื่อ Emote ต้องเชื่อมกับระบบอื่น เช่น

Job
Inventory
Metadata
Permissions

64. Emote Menu ทำให้ FPS ตกไหม

ตัว Menu เองไม่ควรถูกสรุปว่าเป็นสาเหตุโดยอัตโนมัติ

ต้องดู

Client Loops
NUI
Animation Logic
Props
จำนวน Objects
Control Loops

Resource ที่เขียน Loop ตรวจทุก Frame จำนวนมากโดยไม่จำเป็นอาจใช้ Client CPU มากกว่ารายการ Animation ที่เก็บอยู่เฉย ๆ

65. Emote 1,000 ท่าทำให้ Server Lag ไหม

จำนวน Config Entries อย่างเดียวไม่ใช่คำตอบ

ต้องดูว่า Resource ทำอะไรกับข้อมูลเหล่านั้น

ถ้ารายการอยู่ใน Table แล้วถูกเปิดค้นหาเมื่อผู้เล่นใช้ Menu ผลต่างจาก Script ที่ Iterate รายการทั้งหมดทุก Frame อย่างมาก

จึงควรวัด Runtime ไม่ใช่มองเพียงจำนวน Emotes

66. Prop Emotes จำนวนมากมีผลกับ Performance ไหม

มีโอกาสถ้า Objects ถูกสร้างจำนวนมากและไม่ Cleanup

ตัวอย่างปัญหา

ผู้เล่น 100 คน
×
Prop ค้างคนละ 5 ชิ้น
=
500 Objects ที่ไม่จำเป็น

ดังนั้น Prop Lifecycle สำคัญมาก

67. Emote Menu ควรมี Search ไหม

สำหรับ Server ที่มี Emote จำนวนมาก Search ช่วย UX มาก

เช่นค้นหา

dance
sit
phone
police

โดยไม่ต้องแสดงทุก Animation ในหน้าจอเดียว

สิ่งนี้เป็นเรื่อง UX ของ Resource มากกว่า Animation Engine

68. Favorite Emotes มีประโยชน์ไหม

มี

ผู้เล่นมักใช้เพียงบาง Emote ซ้ำ

ระบบ Favorite หรือ Quick Slot ช่วยลดการเปิด Menu หลายขั้น

เช่น

1 = Wave
2 = Cross Arms
3 = Sit
4 = Phone

แต่ควรแยก Favorite ID ออกจาก Animation Dictionary โดยตรง เพื่อให้เปลี่ยน Animation Data ภายหลังได้ง่าย

69. Keybind Emote ควรทำอย่างไร

ควรให้ Keybind เรียก Logical Emote Name

เช่น

favorite_1
→ crossarms

จากนั้น Resource จึง Resolve

crossarms
→ dict
→ anim
→ flags

ดีกว่า Hard-code Dictionary/Animation ในทุก Keybind

70. วิธี Debug FiveM Animation ไม่เล่นแบบเร็วที่สุด

ใช้ลำดับนี้

ขั้นที่ 1 — ตรวจ Ped

local ped = PlayerPedId()

ขั้นที่ 2 — ตรวจ Animation Dictionary

เรียก

RequestAnimDict(dict)

REQUEST_ANIM_DICT ใช้ Request Dictionary สำหรับ Script.

ขั้นที่ 3 — รอ Dictionary

while not HasAnimDictLoaded(dict) do
    Wait(0)
end

HAS_ANIM_DICT_LOADED ใช้ตรวจ Loading State.

ขั้นที่ 4 — ตรวจ Animation Name

ให้ตรงกับ Dictionary

ขั้นที่ 5 — TaskPlayAnim

TaskPlayAnim(...)

ตรวจ Duration และ Flags.

ขั้นที่ 6 — ถ้า Scenario

ใช้

TASK_START_SCENARIO_IN_PLACE

แทน Animation Flow.

ขั้นที่ 7 — ถ้ามี Prop

ตรวจ

Model
Bone
Offset
Rotation
Attachment

ขั้นที่ 8 — ถ้า Cancel ไม่ได้

ตรวจ

STOP_ANIM_TASK
CLEAR_PED_TASKS

ตามสิ่งที่ Resource ต้องการหยุด.

ขั้นที่ 9 — Cleanup Prop

อย่าหยุด Animation อย่างเดียว

ขั้นที่ 10 — Reset Resource State

เช่น

isEmoting = false
activeProp = nil

ตาม Implementation ของระบบ

ตารางสรุปปัญหา FiveM Animation และ Emote Menu

อาการจุดที่ควรตรวจ
Animation ไม่เล่นAnim Dict / Anim Name
Dict โหลดไม่เสร็จREQUEST_ANIM_DICT
Dict โหลดแล้วแต่ไม่มีท่าAnimation Name
Animation เล่นครั้งเดียวDuration / Flags
Animation Loop ไม่หยุดFlags / Cancel
Cancel แล้วท่ายังค้างTask/State
Cancel แล้วเดินไม่ได้Control/State Logic
Emote เดินไม่ได้Full-body / Flags
ควรอยู่กับที่แต่ยังเดินได้Flags
Scenario ไม่ทำงานScenario Name / Ped
Prop ไม่ขึ้นObject Model
Prop ลอยจากมือBone / Offset
Prop กลับด้านRotation
Prop ค้างหลัง CancelCleanup
Prop ซ้ำDelete Logic
Menu ไม่เปิดResource/NUI
Menu เปิดแต่ Emote ไม่เล่นEvent/Animation Data
Emote บางอันใช้ได้บางอันไม่ได้Entry Data
Shared Emote ไม่ตรงกันSynchronization
Death แล้ว Emote ค้างLifecycle Cleanup

Checklist Emote หนึ่งรายการก่อนเพิ่มเข้า Server

☐ Anim Dict ถูก
☐ Anim Name ถูก
☐ Dict โหลดได้
☐ Animation เล่นได้
☐ Duration เหมาะ
☐ Flags เหมาะ
☐ เดินได้/ไม่ได้ตามต้องการ
☐ Cancel ได้
☐ Prop Model ถูกถ้ามี
☐ Bone ถูก
☐ Position Offset ถูก
☐ Rotation ถูก
☐ Prop Cleanup ได้
☐ Death แล้ว Cleanup
☐ Vehicle แล้ว Cleanup
☐ Resource Restart แล้วไม่ค้าง

โครงสร้าง Emote Data ที่ดูแลง่าย

ตัวอย่าง

local Emotes = {
    wave = {
        type = 'animation',
        dict = 'example_dict',
        anim = 'example_anim',
        duration = -1,
        flags = 49,
        canMove = true
    },

    coffee = {
        type = 'animation',
        dict = 'example_dict',
        anim = 'example_anim',
        duration = -1,
        flags = 49,

        prop = {
            model = 'prop_example',
            bone = 57005,
            position = {
                x = 0.10,
                y = 0.02,
                z = 0.00
            },
            rotation = {
                x = 0.0,
                y = 90.0,
                z = 180.0
            }
        }
    }
}

ตัวอย่างนี้เป็น Architecture เชิงแนวคิด จุดสำคัญคือแยก Data ออกจาก Logic เพื่อให้เพิ่มหรือแก้ Emote ได้ง่าย

ตัวอย่าง Function โหลด Animation Dictionary

local function loadAnimDict(dict)
    if HasAnimDictLoaded(dict) then
        return true
    end

    RequestAnimDict(dict)

    local timeout = GetGameTimer() + 10000

    while not HasAnimDictLoaded(dict) do
        Wait(0)

        if GetGameTimer() >= timeout then
            return false
        end
    end

    return true
end

Function นี้ใช้ Native REQUEST_ANIM_DICT และ HAS_ANIM_DICT_LOADED ตามระบบ Animation Streaming ของ FiveM.

ตัวอย่าง Function เล่น Emote แบบพื้นฐาน

local function playEmote(dict, anim, duration, flags)
    local ped = PlayerPedId()

    if not loadAnimDict(dict) then
        print('Failed to load animation dictionary:', dict)
        return
    end

    TaskPlayAnim(
        ped,
        dict,
        anim,
        8.0,
        -8.0,
        duration or -1,
        flags or 0,
        0.0,
        false,
        false,
        false
    )
end

TASK_PLAY_ANIM รองรับ Dictionary, Animation Name, Blend Speeds, Duration และ Flags ตาม Native Reference.

ตัวอย่าง Cancel Emote ที่ถูกแนวคิด

local activeProp = nil

local function cancelEmote()
    local ped = PlayerPedId()

    ClearPedTasks(ped)

    if activeProp and DoesEntityExist(activeProp) then
        DeleteEntity(activeProp)
    end

    activeProp = nil
end

แนวคิดสำคัญคือ Cancel ต้องจัดการทั้ง Ped Task และ Object State ไม่ใช่หยุด Animation เพียงอย่างเดียว โดย CLEAR_PED_TASKS ใช้หยุด Script-created Ped Tasks.

Emote Menu ที่ดีควรมีอะไร

สำหรับ Server Roleplay ควรพิจารณา

Animation Categories
Search
Favorites
Cancel Emote
Keybind
Prop Support
Scenario Support
Movement Rules
Vehicle Rules
Death Cleanup
Resource Cleanup
Permissions
Shared Emotes

โดยไม่จำเป็นต้องเปิดทุก Feature ตั้งแต่แรก

ความเสถียรของ Animation/Prop Lifecycle สำคัญกว่าจำนวน Emote

Emote Categories ควรแบ่งอย่างไร

ตัวอย่าง

General
Dance
Sitting
Standing
Police
Work
Expression
Prop Emotes
Scenarios
Shared Emotes

ช่วยให้ผู้เล่นหา Animation ได้ง่ายกว่า Menu รายการยาวหลายร้อยตัว

Shared Emote ต้องขออนุญาตอีกฝ่ายไหม

สำหรับระบบ Roleplay ที่ผู้เล่นสองคนต้องถูกจัด Position หรือ Animation ร่วมกัน ควรออกแบบให้ Target ยอมรับก่อน

เช่น

Player A ส่งคำขอกอด
↓
Player B Accept
↓
ตรวจ Distance
↓
จัด Position
↓
เล่น Animation

ป้องกันการบังคับ Animation ผู้เล่นอื่นแบบไม่ตั้งใจ

Emote Resource ควรเชื่อถือ Client ทั้งหมดไหม

ไม่ควรสำหรับ Action ที่มีผลต่อ Gameplay/Permissions

Animation Visual สามารถทำงานฝั่ง Clientได้ แต่ถ้า Emote เชื่อมกับ

Item
Job
Restraint
Gameplay Reward
Target Player

ควร Validate Logic สำคัญใน Layer ที่เหมาะสม

Animation ไม่ควรถูกใช้เป็นหลักฐานว่าผู้เล่นมี Permission หรือ Item จริง

Animation กับ Custom Ped มีปัญหาอะไรได้บ้าง

Custom Ped อาจมี Skeleton หรือ Proportions ต่างจาก Ped ที่ Animation ถูกสร้างมาสำหรับ

จึงอาจเกิด

แขนบิด
ขาบิด
มือไม่ตรง Prop
Character จมพื้น
Emote ดูผิดรูป

ถ้า Freemode Ped เล่น Animation ปกติ แต่ Custom Ped พัง ให้ตรวจ Rig/Skeleton ของ Custom Ped ก่อนเปลี่ยน Animation Dictionary

Prop Alignment กับ Custom Ped อาจไม่ตรง

Bone เดียวกันไม่ได้รับประกันว่า Visual Position จะเหมือนกันบนทุก Character Model

Custom Ped ที่

ตัวสูงกว่า
แขนยาวกว่า
มือใหญ่กว่า

อาจต้องใช้ Prop Offset คนละชุดจาก Freemode Ped

ดังนั้น Emote Menu ระดับสูงอาจต้องรองรับ Offset ตาม Ped Model

Scenario เหมาะกับ NPC มากไหม

เหมาะกับ NPC หลายประเภท เพราะสามารถสร้าง Behavior ที่ดูเป็นธรรมชาติ เช่น NPC ทำกิจกรรมประจำจุด

FiveM มีทั้ง TASK_START_SCENARIO_IN_PLACE และ TASK_START_SCENARIO_AT_POSITION สำหรับเริ่ม Scenario ณตำแหน่งปัจจุบันหรือจุดที่กำหนด.

สำหรับ Shop NPC หรือ Worker NPC จึงไม่จำเป็นต้องสร้าง Animation Loop เองทุกครั้ง

Animation กับ Scenario แบบไหนควรเลือก

จำง่าย ๆ

ต้องการท่าที่ควบคุมละเอียด
→ Animation

ต้องการ Activity สำเร็จรูปของ GTA
→ Scenario

ต้องการ Object + ท่าเฉพาะ
→ Animation + Prop

ต้องการหลายคน/หลาย Entity Sync แม่น
→ พิจารณา Synchronised Scene

ไม่มีแบบใดดีที่สุดทุกงาน

สิ่งที่ไม่ควรทำกับ FiveM Animation

หลีกเลี่ยง

เล่น Animation ก่อน Dict โหลด
Loop รอ Dict โดยไม่มี Wait
ใช้ Flags เดียวกับทุก Animation
Create Prop ใหม่โดยไม่ลบของเก่า
ClearPedTasks ทุก Frame
Disable Controls แต่ไม่ Reset State
ไม่ Cleanup ตอนตาย
ไม่ Cleanup ตอน Resource Stop
ใช้ Full-body Animation แล้วคาดว่าจะเดินได้ทุกอัน
บังคับ Shared Emote อีกฝ่ายโดยไม่ตรวจ

ปัญหา Emote จำนวนมากไม่ได้เกิดจาก Animation File แต่เกิดจาก State และ Lifecycle Management ของ Resource

สูตรจำง่ายสำหรับ FiveM Animation

LOAD
↓
PLAY
↓
PROP
↓
STATE
↓
CANCEL
↓
CLEANUP

ถ้า Emote มีปัญหา ให้ Debug ตามลำดับนี้

สรุป FiveM Animation และ Emote Menu คืออะไร

FiveM Animation คือระบบที่ทำให้ Ped เล่นท่าทางหรือการเคลื่อนไหว ส่วน Emote Menu คือ UI/Resource ที่นำ Animation เหล่านั้นมาจัดเป็นรายการให้ผู้เล่นเรียกใช้งานได้สะดวก

Flow หลักของ Animation คือ

Animation Dictionary
↓
REQUEST_ANIM_DICT
↓
HAS_ANIM_DICT_LOADED
↓
TASK_PLAY_ANIM

Cfx.re มี Native ทั้งสามส่วนสำหรับโหลด Dictionary ตรวจ Loading State และเล่น Animation โดยกำหนด Blend, Duration และ Flags ได้.

หาก Animation ไม่เล่น ให้ตรวจ Anim Dict และ Anim Name

หาก Dictionary ไม่โหลด ให้ตรวจ REQUEST_ANIM_DICT และ Loop ที่รอ HAS_ANIM_DICT_LOADED

หาก Animation เล่นแต่เดินไม่ได้หรือ Loop ผิด ให้ตรวจ Flags และ Task Behavior

หาก ต้องการ Activity สำเร็จรูปของ GTA สามารถใช้ Scenario ผ่าน TASK_START_SCENARIO_IN_PLACE หรือ TASK_START_SCENARIO_AT_POSITION.

หาก Emote มีแก้ว โทรศัพท์ กล่อง หรือ Prop อื่น ต้องจัดการ Object, Bone, Offset, Rotation และ Cleanup แยกจาก Animation

หาก กดยกเลิกแล้วท่าค้าง สามารถใช้ STOP_ANIM_TASK สำหรับ Animation เฉพาะ หรือ CLEAR_PED_TASKS เมื่อต้องการ Clear Script-created Ped Tasks ตาม Architecture ของ Resource.

และเมื่อไม่ต้องการ Animation Dictionary ต่อแล้ว FiveM มี REMOVE_ANIM_DICT สำหรับ Release Dictionary จากการใช้งานของ Script.

สำหรับ Shared Emotes หรือ Animation ที่ต้อง Synchronize ผู้เล่น/Entities หลายตัวอย่างแม่นยำ FiveM ยังมี Network Synchronised Scene APIs ซึ่งเหมาะกว่าการสั่ง TASK_PLAY_ANIM แยกแต่ละ Ped แบบอิสระ.

แนวทางของ comsiam คือมอง Emote หนึ่งรายการเป็นมากกว่า Animation Name เพราะระบบที่สมบูรณ์ต้องจัดการ Dictionary, Animation, Flags, Prop, State, Cancel และ Cleanup ให้ครบ หากวางโครงสร้างเหล่านี้ดีตั้งแต่ต้น แม้ Server จะเพิ่ม Emote หลายร้อยหรือหลายพันรายการก็ยังดูแลและแก้ปัญหาได้ง่าย

Comments

Popular posts from this blog

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

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

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