Lua API
Fightura ลงทะเบียน global Lua ชื่อ fightura ให้ avatar Figura ทุกตัว มีฟีเจอร์: query สถานะ Epic Fight, อ่าน joint pose, และ override ชื่อ bone ตอน runtime
if fightura:isAvailable() then -- entity นี้มี Epic Fight patch ติดอยู่endQuery สถานะ
Section titled “Query สถานะ”isAvailable() -> boolean
Section titled “isAvailable() -> boolean”true ถ้า entity มี LivingEntityPatch ของ Epic Fight ติดอยู่ ตรวจตัวนี้เป็นอันดับแรกทุกครั้ง — ถ้าไม่มี method อื่น ๆ จะคืน nil หรือ false
isEpicFightMode() -> boolean
Section titled “isEpicFightMode() -> boolean”true ตอน player อยู่ใน battle stance ของ Epic Fight (ชักดาบ ฯลฯ)
isAttacking() -> boolean
Section titled “isAttacking() -> boolean”true ตลอด animation การโจมตีของ Epic Fight
hasPose() -> boolean
Section titled “hasPose() -> boolean”true ถ้ามี pose snapshot ปัจจุบันของ frame นี้ ใช้ใน events.RENDER ก่อนเรียก joint query
function events.WORLD_TICK() if fightura:isAttacking() then -- เล่น animation reaction ที่ทำเอง endendอ่าน joint pose
Section titled “อ่าน joint pose”อ่านจาก pose snapshot ล่าสุดของ Epic Fight (update ทุก frame ที่ entity ถูก render)
getJointRotation(name: string) -> Vector3 | nil
Section titled “getJointRotation(name: string) -> Vector3 | nil”คืน rotation ของ joint เป็น ZYX Euler ในหน่วย radians คืน nil ถ้าไม่พบ joint ใน armature ปัจจุบัน
function events.RENDER(delta) if not fightura:hasPose() then return end local rot = fightura:getJointRotation("Hand_L") if rot then models.MyArm.LowerArm:setRot( math.deg(rot.x), math.deg(rot.y), math.deg(rot.z) ) endendgetJointMatrix(name: string) -> Matrix4 | nil
Section titled “getJointMatrix(name: string) -> Matrix4 | nil”คืน 4×4 matrix ของ joint เต็มรูปแบบ (เป็น FiguraMat4) เหมาะกับ rig ที่ใช้ matrix
local headMat = fightura:getJointMatrix("Head")if headMat then models.MyHat:setMatrix(headMat)endgetJoints() -> string[]
Section titled “getJoints() -> string[]”คืนรายการชื่อ joint ทั้งหมดใน armature ของ entity ตอนนี้ ใช้สำรวจว่ามีอะไรบ้าง — mob/player คนละตัวอาจมี rig ต่างกัน
for _, joint in pairs(fightura:getJoints()) do print(joint)endBone binding
Section titled “Bone binding”ถ้า avatar ใช้ชื่อ part ที่ Fightura ไม่รู้จัก ผูกครั้งเดียวตอน load ดู รูปแบบการตั้งชื่อ สำหรับรายการ alias เต็ม
mapBone(alias: string, joint: string)
Section titled “mapBone(alias: string, joint: string)”ผูกชื่อ part (หรือชื่อ parentType) กับ Epic Fight joint Alias ฝั่ง case-insensitive ส่วนชื่อ joint ต้องตรงเป๊ะ (Head, Chest, Arm_L, Hand_L, Thigh_L, Leg_L, …)
function events.LOAD() fightura:mapBone("MyTailRoot", "Pelvis") fightura:mapBone("LSleeveCuff", "Hand_L")endOverride มีผลเฉพาะ avatar ตัวนี้ ไม่ leak ไปยังผู้เล่นอื่น
clearBone(alias: string)
Section titled “clearBone(alias: string)”ลบ override อันเดียว
fightura:clearBone("MyTailRoot")clearBones()
Section titled “clearBones()”ลบ override ทั้งหมดของ avatar นี้
getSupportedBones() -> string[]
Section titled “getSupportedBones() -> string[]”คืนรายการ alias built-in ทั้งหมดที่ Fightura รู้จัก (ในรูปแบบ lowercase) ใช้ตรวจว่าชื่อไหนไม่ต้อง mapBone
Epic Fight events
Section titled “Epic Fight events”Fightura ยิง Lua event เมื่อสถานะ Epic Fight ของ entity เปลี่ยน — ไม่ต้อง poll เอง แต่ละ event เป็น LuaEvent field บน fightura API ลงทะเบียน handler ด้วย :register(func)
function events.LOAD() fightura.attackStart:register(function(motion) -- motion คือชื่อ living motion ตอนนี้ (เช่น "ATTACK") animations.MyAttackReact:play() end)
fightura.attackEnd:register(function() animations.MyAttackReact:stop() end)
fightura.modeChange:register(function(newMode, oldMode) if newMode == "BATTLE" then animations.DrawSword:play() elseif newMode == "MINING" then animations.SheathSword:play() end end)
fightura.hurtStart:register(function() animations.HurtFlinch:play() end)
fightura.knockDown:register(function() animations.KnockedDown:play() end)
fightura.motionChange:register(function(newMotion, oldMotion) -- เช่น เปลี่ยนจาก "IDLE" ไป "WALK" end)end| Event | Args | ยิงเมื่อ |
|---|---|---|
attackStart | motion: string | Epic Fight animation โจมตีเริ่ม |
attackEnd | (none) | Animation โจมตีจบ |
hurtStart | (none) | Entity เข้าสู่สถานะ hurt |
knockDown | (none) | Entity ถูกล้ม |
modeChange | newMode, oldMode: string | playerMode เปลี่ยน (BATTLE / MINING / DEFAULT) |
motionChange | newMotion, oldMotion: string | Living motion ปัจจุบันเปลี่ยน |
Event ยิงตอน client tick ส่วน method แบบ poll (isAttacking(), isEpicFightMode()) ยังใช้ได้ตามปกติเหมาะกับ logic ที่รันทุก frame
Pattern พื้นฐาน
Section titled “Pattern พื้นฐาน”สคริปต์เริ่มต้นที่เหมาะสม:
function events.LOAD() -- ผูกชื่อ part ที่ไม่ standard ครั้งเดียว fightura:mapBone("HornLeft", "Head") fightura:mapBone("HornRight", "Head") fightura:mapBone("TailRoot", "Pelvis")end
function events.WORLD_TICK() if fightura:isAvailable() and fightura:isAttacking() then -- trigger animation reaction endend
function events.RENDER(delta) if not fightura:hasPose() then return end
-- transform per-frame ขับโดย Epic Fight pose local hand = fightura:getJointRotation("Hand_L") if hand then models.weapon_glow:setRot(math.deg(hand.x), math.deg(hand.y), math.deg(hand.z)) endendสิ่งที่ตั้งใจไม่ exposeเพื่อให้ surface เล็ก เราไม่ใส่:
Section titled “สิ่งที่ตั้งใจไม่ exposeเพื่อให้ surface เล็ก เราไม่ใส่:”- การแก้ armature โดยตรง (อ่านอย่างเดียว)
- trigger Epic Fight skill
- sniff network packet
- query สถานะ vanilla model (ใช้ Figura
vanilla_modelAPI แทน)
ถ้าต้องการอะไรนอกเหนือจากนี้ เปิด issue ที่ GitHub
- แก้ปัญหา — ทำยังไงเมื่อ method คืน
nilทั้งที่ควรมีข้อมูล