ניווט אויבים בתלת-ממד: מתקיעה לתנועה טבעית
NavMeshAgent תקוע בפינה. או מסתובב במעגלים סביב מכשול כשהוא יכול לעקוף אותו בשנייה. או משתגר דרך קיר בעת שינוי סצנה. בעיות בניווט AI בתלת-ממד אינן "משהו השתבש" אלא החלטות ארכיטקטוניות ספציפיות שמתחשבות במגבלות NavMesh או לא. ב-VR הדברים חדים יותר: השחקן נמצא פיזית במרחב המשחק, זז בעצמו, והאויבים חייבים להגיב לתנועה הזו מיד. אויב ש"חושב" 200 אלפיות השנייה לפני פנייה מורגש ב-VR כמו שלא היה מעולם. הוסף גמגום בהתנהגות קבוצתית, ותקציב ה-FPS נסדק. הניסיון שלנו מראה שתצורה נכונה של NavMesh ומערכות נוספות משתלמת כבר בשלב האב-טיפוס. אנו מבטיחים שאחרי העידון שלנו, אויבים יפסיקו "להתמהמה" וינועו באופן טבעי. הזמינו הערכה של הפרויקט שלכם — נבחר פתרון למשימות ולתקציב ה-FPS שלכם. חיסכון בתקציב FPS מ-LOD ו-batching יכול להגיע ל-20%.
מדוע NavMeshAgent נתקע בתפרים?
הסיבה היא שמספר NavMeshSurface אינם מחוברים אוטומטית. בתפרים, סוכנים מאבדים את הנתיב. פתרון: השתמשו במשטח יחיד עם NavMeshLink לגשרים, או הוסיפו במפורש רכיבי NavMeshLink בנקודות מעבר. אם בסצנה יש 5+ משטחים, תפירה ידנית היא חובה.
הסוכן אינו מעדכן את הנתיב כשהשחקן זז. SetDestination נקרא פעם אחת כשהשחקן מזוהה, והסוכן הולך לנקודה שבה היה השחקן. יש צורך בעדכון נתיב תקופתי — כל 0.2–0.5 שניות קראו ל-SetDestination עם המיקום הנוכחי של המטרה. לעתים קרובות מדי — עומס CPU מחישוב נתיב חוזר מתמיד. לעתים רחוקות מדי — האויב "מפגר". פשרה: עדכנו רק אם המטרה זזה יותר מ-destinationChangeThreshold מטרים (0.5 מ' הוא ערך טוב).
הסוכן עובר דרך סוכנים אחרים. NavMeshAgent.radius הוא הרדיוס להימנעות ממכשולים, אבל הוא עובד רק עם NavMeshObstacle וסוכנים אחרים. אם לסוכן יש avoidancePriority נמוך יותר מאשר לאחר, הוא נכנע ועלול "להידחף" לתוך עצמים. הגדירו עדיפויות: אויבים רגילים — 50, בוסים — 20, שחקן — 10 (מספר נמוך יותר = עדיפות גבוהה יותר). בפועל, זה מפחית הידבקות קבוצתית ב-40%.
כיצד ליישם תנועה חלקה באמצעות Steering Behaviour?
NavMesh מספק נתיב גלובלי מ-A ל-B. אבל תנועה לאורך הנתיב היא משימה נפרדת. steeringTarget הסטנדרטי יכול לתת תנועה זוויתית: הסוכן מבצע פנייה חדה של 90° במקום חלקה.
פתרון: השבתו את updateRotation, וסובבו את הסוכן בעצמכם באמצעות Quaternion.RotateTowards עם מהירות זוויתית התואמת לאופי הדמות. זומבי איטי — 60°/שנייה, לוחם מהיר — 180°/שנייה. זה מיד הופך את התנועה למשכנעת יותר.
להתנהגות מורכבת יותר — Steering Behaviours על גבי NavMesh: Seek (לכיוון המטרה), Flee (הרחק מהמטרה), Separation (התפזרות מעמיתים). Separation חשוב במיוחד עבור קבוצת אויבים ב-VR — בלעדיו כולם משתגרים לנקודה אחת. Separation מיושם ככוח נוסף המתווסף למהירות הרצויה: קחו את כל הסוכנים בטווח separationRadius (2 מ'), סכמו וקטורים "הרחק מכל אחד", נרמלו, והוסיפו כקיזוז ל-velocity. גישה זו מתוארת בעבודה Steering Behaviours for Autonomous Characters (Craig Reynolds).
| גישה | מורכבות | יישום |
|---|---|---|
| NavMeshAgent סטנדרטי | נמוכה | אויבי סיור פשוטים |
| Steering על NavMesh | בינונית | קבוצות, מסלולים חלקים |
| Behaviour Tree + Steering | גבוהה | התנהגות מורכבת עם עדיפויות |
Behaviour Tree לעומת State Machine: מה לבחור ל-VR?
State Machine (באמצעות Animator Controller או קוד) — פשוט יותר ליישום, אבל מתרחב בצורה גרועה. עם 5+ מצבים, מעברים הופכים לספגטי.
Behaviour Tree (BT) — מבנה משימות היררכי. אויב: Selector → [Attack אם מרחק < 2מ' → Chase אם רואה שחקן → Patrol אחרת]. כל צומת הוא Sequence (כל הילדים חייבים להצליח), Selector (כל אחד מצליח), או Leaf (פעולה ספציפית). ל-VR חשוב: BTs צריכים להתעדכן בתדרים שונים בהתאם למרחק מהשחקן. אויב במרחק 30 מ' — עדכון BT פעם בשנייה. אויב במרחק 3 מ' — כל 100 אלפיות השנייה. DistanceBasedUpdateRate מפחית עומס CPU ב-30% עם 50+ סוכנים.
מודעות מרחבית: שמיעה וראייה
חרוט ראייה מיושם באמצעות Physics.OverlapSphere + בדיקת זווית + Linecast לבדיקת נראות. אספו מטרות בטווח sightRange (20 מ'), סננו לפי Vector3.Angle < fieldOfView / 2 (לדוגמה, 45° לאדם), בדקו Linecast למכשולים.
למשחקי VR, הוסיפו בדיקה לגירויי קול: השחקן יורה או רץ → נוצר אירוע SoundStimulus עם מיקום ועוצמה → כל הסוכנים ברדיוס intensity * attenuationFactor (לדוגמה, 10 מ' לירייה) מקבלים הודעה. השתמשו ב-Unity Events או ב-Physics.OverlapSphere מנקודת הקול. מערכת זו שומרת על FPS יציב גם עם 20+ סוכנים.
כיצד להגדיר NavMesh אופטימלי: מדריך שלב-אחר-שלב
- הגדרות Bake: הגדירו Agent Radius מינימלי תואם לגיאומטריה (0.3 מ'), Step Height — לגובה המכשול הקטן ביותר (0.2 מ').
-
תפירת משטחים: אם הסצנה מחולקת למספר
NavMeshSurface, הוסיפוNavMeshLinkבמעברים מפורשים (דלתות, גשרים). -
בדיקת תקיעה: השתמשו ב-
NavMeshAgent.pathStatusוב-NavMeshAgent.desiredVelocity— אם הסטטוס הואPathPartial, חשבו מחדש נתיב עם נקודת התחלה חדשה. -
פרופילינג: ב-Profiler הסתכלו על
NavMeshUpdateו-Pathfinding— הם לא צריכים לחרוג מ-5% מתקציב ה-CPU.
טעויות אופייניות בהגדרת NavMesh:
- שימוש ב-
NavMeshObstacleעםcarve: true— carve יקר, עדיף לסמן מכשולים סטטיים ב-bake. - חסר
NavMeshAgent.areaMask— סוכנים עלולים ללכת באזורים לא רצויים. - קריאה ל-
SetDestinationלעתים קרובות מדי (כל פריים) — גורמת להקפאות עם 30+ סוכנים.
מה כלול בפיתוח AI לאויבים?
- ביקורת על מערכת הניווט הנוכחית (NavMesh, רשת, סוכנים)
- עיצוב ויישום של Behaviour Tree או FSM עם התאמות ל-VR
- הגדרת חיישנים (ראייה, שמיעה) עם פרמטרים בזמן אמת
- אופטימיזציה: עדכון מונע LOD, batching, הפחתת draw calls
- אינטגרציה עם משחקיות (אנימציות, התקפה, מעברים)
- תיעוד והכשרת צוות (סדנה של 1–2 שעות)
- תמיכה טכנית למשך שבועיים לאחר המסירה
לוחות זמנים ועלות משוערים
| היקף | לוחות זמנים |
|---|---|
| ניווט בסיסי (NavMeshAgent + מרדף/סיור) | 1–2 שבועות |
| Behaviour Tree + קבוצות אויב + Steering | 3–6 שבועות |
| מערכת AI מלאה עם תפיסה ו-LOD | 2–4 חודשים |
העלות מחושבת באופן אישי לאחר ניתוח דרישות התנהגות האויב ומספר הסוכנים הפעילים בו-זמנית. קבלו ייעוץ מהמהנדס שלנו — נשלח הערכה ראשונית תוך יומיים. אופטימיזציה של תקציב FPS באמצעות LOD ו-batching יכולה לחסוך עד 20% מתקציב הפרויקט. אנו עובדים על פרויקטים של פיתוח משחקים למעלה מ-5 שנים ויישמנו AI עבור 15+ משחקי VR.





