สรุปวิธี Enemy Detection ทั้ง 4 รูปแบบที่นิยมที่สุดใน Roblox พร้อมจุดแข็งและจุดอ่อน

Roblox Studio Enemy Detection

1. Distance / Magnitude Checking

วิธีนี้พื้นฐานที่สุดและประหยัดทรัพยากร (Performance) ที่สุดครับ เราจะใช้คุณสมบัติ Magnitude ของ Vector3 เพื่อหาระยะห่างระหว่างสองจุด

หลักการ: คำนวณระยะทางแบบเส้นตรง (เหมือนลากสายวัด) ระหว่าง Enemy และ Player

การใช้งาน:

```lua local distance = (Enemy.Position - Player.Position).Magnitude if distance <= 20 then -- ตรวจพบศัตรูในระยะ 20 studs end

ข้อดี: เขียนง่ายมาก, กินสเปคน้อยมาก

2. Line of Sight (Raycasting)

ถ้าอยากให้ AI ดูสมจริงขึ้น ไม่มองทะลุกำแพง เราต้องใช้ Raycasting หรือการยิงเลเซอร์ล่องหนออกไปเช็คครับ

หลักการ: ยิงลำแสงจากตาของ AI ไปยังเป้าหมาย ถ้าลำแสงไปโดน Player ก่อนจะโดนกำแพง แสดงว่า “มองเห็น”

การใช้งาน:

workspace:Raycast(origin, direction, params)

ข้อดี: ป้องกันการมองทะลุสิ่งของ, ใช้ทำระบบลอบเร้น (Stealth) ได้ดี

ข้อเสีย: ถ้ามี AI จำนวนมหาศาล (เช่น 100+ ตัว) ยิง Raycast พร้อมกันทุก Frame อาจทำให้เซิร์ฟเวอร์หน่วงได้

3. Field of View (FOV / Dot Product)

วิธีนี้ใช้ตรวจจับว่าศัตรูอยู่ “ข้างหน้า” หรือ “ข้างหลัง” ของ AI โดยใช้คณิตศาสตร์ Vector ที่เรียกว่า Dot Product

หลักการ: คำนวณหาค่าความต่างของทิศทางที่ AI มองอยู่ กับทิศทางที่ Player อยู่ หากค่าที่ได้อยู่ในช่วงที่กำหนด (เช่น 45 องศา) แสดงว่าอยู่ในระยะสายตา
สูตรทางคณิตศาสตร์: เรามักจะใช้สมการ $A \cdot B = |A||B|\cos(\theta)$ เพื่อหาค่า Cosine ของมุมการใช้งาน:

lualocal npcToPlayer = (Player.Position - Enemy.Position).Unitlocal lookVector = Enemy.CFrame.LookVectorlocal dot = lookVector:Dot(npcToPlayer)if dot > 0.5 then -- ประมาณ 60 องศาด้านหน้า-- อยู่ใน FOV end 

ข้อดี: สมจริง AI จะไม่เห็นเราถ้าเราย่องไปข้างหลัง
ข้อเสีย: ต้องใช้ร่วมกับ Magnitude และ Raycasting เพื่อให้ได้ระบบที่สมบูรณ์ที่สุด

4.Hitbox Detection (Spatial Queries)

วิธีนี้เน้นการตรวจจับเชิงพื้นที่ (Area) มักใช้กับบอสที่มีระยะการโจมตีเป็นวงกว้าง หรือกับกับดัก

หลักการ: สร้างโซนล่องหนขึ้นมา (Hitbox) แล้วเช็คว่ามีใครอยู่ในนั้นไหม ปัจจุบัน Roblox แนะนำให้ใช้ OverlapParams และฟังก์ชันกลุ่ม GetPartBoundsInBox หรือ GetPartsInPart

การใช้งาน:

lua local params = OverlapParams.new() params.FilterDescendantsInstances = {Enemy} local results = workspace:GetPartBoundsInBox(HitboxPart.CFrame, HitboxPart.Size, params)

ข้อดี: เหมาะมากกับการตรวจจับหลายเป้าหมายพร้อมกัน (AOE), กำหนดรูปร่างพื้นที่ได้ชัดเจน

ข้อเสีย: ถ้า Hitbox ใหญ่เกินไปหรือเช็คบ่อยเกินไป อาจส่งผลต่อ Performance ได้