פיתוח מערכת התנגשויות למשחקי מובייל
אתה משיק משחק ריצה באנדרואיד, והדמות נופלת דרך פלטפורמה ברמה 60. קצב הפריימים צונח מ-30 ל-20 במכשיר Galaxy A10. תופעות של מעבר דרך אובייקטים (Tunneling) וזיהוי שגוי (False Positives) הם סימפטומים של פיזיקה לא מותאמת. קולידרים סטנדרטיים של Unity ו-Godot עובדים על שולחן העבודה, אבל במכשירים ניידים עם קצב פריימים משתנה והאטת מעבד, מערכת ההתנגשויות נכשלת. לאורך השנים, מיטבנו זיהוי התנגשויות למגוון ז'אנרים של משחקים—מריצה ועד פלטפורמות. עם למעלה מ-40 פרויקטים עם פיזיקה מותאמת אישית, אנו מבטיחים איכות בכל שלב. חיסכון בתקציב על בדיקות ועיבוד מחדש יכול להגיע ל-40%. עלות היישום של פיזיקה מותאמת אישית מופחתת בעד 50%.
בעיות עם קולידרים מובנים במכשירים ניידים
מעבר דרך אובייקטים (Tunneling) — אובייקט שנע במהירות עובר דרך אובייקט אחר בין שני צעדי פיזיקה. void CheckGround() { RaycastHit2D hit = Physics2D.Raycast( transform.position, Vector2.down, groundCheckDistance, groundLayer ); isGrounded = hit.collider != null; if (isGrounded) groundNormal = hit.normal; } void CheckObstacles() { RaycastHit2D hit = Physics2D.BoxCast( transform.position, colliderSize, 0f, Vector2.right, obstacleCheckDistance, obstacleLayer ); if (hit.collider != null) OnObstacleHit(hit); } ב-Unity פותר זאת אך עולה בערך פי 2 יותר במעבד מאשר Discrete. במכשירי אנדרואיד תקציביים, זה מורגש — תיעדנו ירידות של עד 15% בקצב הפריימים בשימוש נרחב ב-Continuous.
זיהויים שגויים במפרקים. PolygonCollider2D עם מספר נקודות קודקוד במפרקי אריחים יוצר לעיתים קרובות התנגשויות פנטום — הדמות מועדת על קרקע שטוחה. ב-Unity, זה נפתר עם CompositeCollider2D, שממזג קולידרים של אריחים שכנים לצורה פוליגונלית אחת. ב-Godot, המקבילה היא TileMap עם מיזוג אוטומטי של צורות התנגשות.
MeshCollider יקר. MeshCollider עם Convex = false ב-Unity אינו משתתף בהתנגשויות דינמי-לדינמי — רק סטטי. אם יש צורך בצורות שרירותיות לאובייקטים דינמיים, קרב עם פרימיטיבים: כמה BoxCollider/CapsuleCollider במקום MeshCollider אחד. זו עבודה ידנית אבל מפחיתה משמעותית את עומס ה-broadphase.
איך להגדיר את מטריצת שכבות ההתנגשות למשחקי מובייל?
הדבר הראשון שאנו מגדירים הוא מטריצת שכבות ההתנגשות (Layer Collision Matrix). טעות אופיינית היא להשאיר את כל השכבות באינטראקציה. במשחק עם 5 סוגי אובייקטים, זה 25 זוגות התנגשות במקום 6-8 שבאמת נחוצים. לפרויקט מובייל, זה משפיע ישירות על ה-broadphase. פחות זוגות פעילים משמעותם פחות עבודה בכל צעד פיזיקה.
| סוגי אובייקטים | כל הזוגות | זוגות מותאמים | חיסכון בבדיקות |
|---|---|---|---|
| 5 | 25 | 8 | 68% |
| 10 | 100 | 20 | 80% |
| 15 | 225 | 35 | 84% |
אופטימיזציה של מטריצת השכבות מניבה עד 84% הפחתה בבדיקות ללא אובדן דיוק. הפחתת עומס מעבד של עד 84% היא רווח אמיתי במכשירים חלשים.
דוגמה להגדרת Fixed Timestep
למכשירי 60 FPS, אנו ממליצים על `Fixed Timestep = 0.0167 שניות`. ל-30 FPS — `0.0333 שניות`. אבל אל תשנה זאת בעיוורון: נמוך מדי גורם לעומס יתר, גבוה מדי מזמין מעבר דרך אובייקטים. בצע פרופיילינג על המכשיר הממוקד.מתי להשתמש ב-Trigger לעומת Collision?
| תרחיש | סוג | דוגמה |
|---|---|---|
| התנגשות פיזית עם ריבאונד | Collision (OnCollisionEnter) | כדור פוגע בקיר |
| חפיפה לוגית ללא פיזיקה | Trigger (OnTriggerEnter) | אזור איסוף פריט |
| בדיקת לחיצת כפתור | Trigger | Raycast בממשק משתמש |
Collision הוא מגע פיזי עם דחף; trigger הוא חפיפה לוגית ללא פיזיקה. טעות נפוצה: שימוש ב-Collision במקום שבו רק Trigger נחוץ, מה שמוסיף Rigidbodies מיותרים ומעמיס על הפותר. ב-Godot 4, המקבילה היא Area2D עבור triggers ו-CharacterBody2D.move_and_collide() עבור אינטראקציות פיזיות. move_and_slide() מחליק אוטומטית לאורך שיפועים — דבר שתצטרך ליישם ידנית ב-Unity באמצעות נורמלים של משטחים.
מתי פיזיקת המנוע היא מוגזמת: Raycast מותאם אישית
לחלק מהז'אנרים, פיזיקת המנוע היא מוגזמת. דוגמה: משחק ריצה שבו נדרשת רק התנגשות עם קרקע ומכשולים. במקום Rigidbody + Collider — מערכת מבוססת raycast:
void CheckGround()
{
RaycastHit2D hit = Physics2D.Raycast( transform.position, Vector2.down, groundCheckDistance, groundLayer );
isGrounded = hit.collider != null;
if (isGrounded)
groundNormal = hit.normal;
}
void CheckObstacles()
{
RaycastHit2D hit = Physics2D.BoxCast( transform.position, colliderSize, 0f, Vector2.right, obstacleCheckDistance, obstacleLayer );
if (hit.collider != null)
OnObstacleHit(hit);
}זה קל יותר, דטרמיניסטי לחלוטין, ונותן שליטה ישירה. אין רעידות אקראיות מאיטרציות של הפותר. במכשירים חלשים, מערכת כזו מהירה פי 2-3 מפיזיקת Rigidbody סטנדרטית. בפרויקט ריצה אחרון, החלפנו פיזיקה סטנדרטית במערכת מבוססת raycast, מה שהפחית את השימוש במעבד פי 2.5 וביטל מעבר דרך אובייקטים במהירויות גבוהות.
איך אנו מייעלים זיהוי התנגשויות: תוכנית שלב-אחר-שלב
- פרופיילינג על מכשיר המטרה. השתמש ב-Unity Profiler (Deep Profile), התמקד ב-
Physics.Processingו-Physics2D.Processing. זהה צווארי בקבוק: Fixed Timestep קטן מדי, אינטרפולציה על עשרות אובייקטים, CompositeCollider2D דינמי. - הגדר את מטריצת השכבות. הסר זוגות מיותרים, הגדר רק אינטראקציות נדרשות. זה מפחית את עומס ה-broadphase בעד 80%.
- בחר סוג גלאי. הפעל Continuous עבור אובייקטים מהירים, שמור על Discrete עבור אחרים. אם נדרשת דטרמיניזם מלא, יישם מערכת מבוססת raycast.
- קרב קולידרים. החלף MeshCollider בשילובי פרימיטיבים. ייעל את PolygonCollider2D באמצעות CompositeCollider2D או TileMap.
- בדוק על 10+ מכשירים. בדוק במכשירי אנדרואיד מובילים ותקציביים. תעד קצב פריימים ושימוש במעבד.
מה כלול בעבודה
- ניתוח הפיזיקה הנוכחית — פרופיילינג על מכשירים אמיתיים, זיהוי צווארי בקבוק.
- עיצוב שכבות התנגשות — הגדרת מטריצה, אופטימיזציה של זוגות.
- יישום גלאים מותאמים אישית — raycast, sweep, AABB כאשר נדרש.
- בדיקות — על 10+ דגמי מכשירים ממובילים ועד תקציביים.
- תיעוד — תיאור מערכת מפורט, המלצות הגדרה.
- הדרכת צוות — סקירה של שימוש ברכיבים.
לוחות זמנים: מכניקה פשוטה — מ-3 עד 5 ימים; מורכבת (עם גיאומטריה מרובת שכבות וגלאי מותאם אישית) — מ-1 עד 3 שבועות. המחיר מתחיל ב-$1500 למערכת ריצה פשוטה. המחיר מחושב באופן אישי — נעריך את הפרויקט שלך. צור קשר לייעוץ. הזמן אופטימיזציה של זיהוי התנגשויות — קבל הערכת פרויקט.
הפתרונות שלנו עוברים את הנחיות הביקורת של App Store ואת Google Play Console ללא בעיות. 8+ שנות ניסיון בפיתוח משחקי מובייל, למעלה מ-40 פרויקטים שהושלמו עם פיזיקה מותאמת אישית, אחריות איכות ותמיכה לאחר מסירה. להבנה מעמיקה יותר, ראה זיהוי התנגשויות.







