קוליידרים שהוגדרו בצורה לא נכונה הם אחת הבעיות הנפוצות והעדינות ביותר בפרויקטים של Unity. אנחנו, כמהנדסים עם ניסיון של 10+ שנים בייצור, רואים את זה כל הזמן: הדמות נופלת דרך הרצפה במהירות גבוהה, כדורים נעלמים בלי לפגוע במטרה, אובייקטים פיזיקליים רועדים על משטח סטטי. הגורמים הם כמעט תמיד יסודות: סוג קוליידר שגוי, חוסר בזיהוי התנגשות רציף (Continuous collision detection), הגדרות שכבות לא נכונות. הצוות שלנו מבטיח לחסל את הבעיות האלה במפתח מוכן — צרו קשר, נעריך את הפרויקט שלכם.
למה קוליידרים מוגדרים לא נכון?
Unity מציעה שישה קוליידרים פרימיטיביים: BoxCollider, SphereCollider, CapsuleCollider, MeshCollider, WheelCollider, TerrainCollider. בנוסף יש מקבילות דו-ממדיות. MeshCollider הוא מקור הבעיות העיקרי בידיים לא מנוסות. Convex MeshCollider עובד נכון עם Rigidbody אבל מוגבל ל-255 פוליגונים. Non-convex לא ניתן להחיל על אובייקטים דינמיים בכלל — Unity תיתן אזהרה אבל לא תחסום את זה, מה שיוביל להתנהגות לא מוגדרת. לדמויות ולקליעים אנחנו תמיד משתמשים בפרימיטיביים; MeshCollider רק לגיאומטריה סטטית של רמות.
CapsuleCollider הוא אופטימלי לדמויות (אנכי) ולקליעים (אופקי). שני פרמטרים: רדיוס וגובה. טעות אופיינית: הקפסולה של הדמות ממוות לפי הרשת החזותית במקום לפי צרכי המשחק — רחבה מדי הופכת את הדמות ל'שמנה' יותר ממה שהיא נראית, כך שהיא לא יכולה לעבור במעברים צרים. SphereCollider הוא הזול ביותר מבחינה חישובית. לקליעים, רימונים ופריטים קטנים, העדיפו CapsuleCollider אם הצורה מאפשרת.
איך להגדיר Layer Matrix?
Physics Layer Collision Matrix (Edit → Project Settings → Physics → Layer Collision Matrix) קובע אילו שכבות מתקשרות. מטריצה לא נכונה מובילה ל: קליעים פוגעים בקבוצה שלהם; אזורי טריגר מגיבים לסביבה במקום רק לשחקן; אויבים דוחפים זה את זה כשהם מקובצים. מבנה שכבות תקין למשחק טיפוסי: Default, Player, Enemy, Projectile, Environment, Trigger, Debris. Projectile מתקשר עם Player, Enemy, Environment — אבל לא עם Trigger, Debris, או Projectile אחר. Trigger אין לו אינטראקציה פיזיקלית — רק OnTriggerEnter. כשמשתמשים ב-Physics.Raycast או Physics.OverlapSphere, תמיד העבירו LayerMask במפורש — בלי מסכה, הבדיקה בודקת את כל השכבות, כולל קוליידרים של ממשק משתמש בלתי נראים ואזורי טריגר, ומחזירה פגיעות לא צפויות.
מצב זיהוי התנגשות: ניצחון על אפקט המנהור
כברירת מחדל, Rigidbody משתמש בזיהוי התנגשות בדיד (Discrete): מיקום האובייקט נבדק בתחילת ובסוף כל FixedUpdate. אם האובייקט נע מהר יותר מ-objectSize / fixedDeltaTime יחידות לשנייה, הוא יכול 'לקפוץ' דרך גיאומטריה דקה — זה אפקט המנהור. כדור בקוטר 0.1 יחידות במהירות 50 מ'/ש' עובר 50 * 0.02 = 1 יחידה לכל FixedUpdate אחד. קיר בעובי 0.5 יחידות יפספס. פתרונות:
- Rigidbody.collisionDetectionMode = CollisionDetectionMode.Continuous — לאובייקטים דינמיים שעלולים לחדור דרך אובייקטים סטטיים
- CollisionDetectionMode.ContinuousDynamic — לאובייקטים שעלולים לחדור דרך אובייקטים דינמיים אחרים
- לקליעים במהירות גבוהה במיוחד, השתמשו ב-Physics.Raycast או Physics.SphereCast במקום Rigidbody פיזיקלי: אמין ויעיל יותר
מצב Continuous הוא אינטנסיבי יותר למעבד. החל רק על קליעים ודמויות מהירים — לא על כל האובייקטים ללא הבחנה.
PhysicMaterial וכיוונון חיכוך
PhysicMaterial מגדיר dynamicFriction, staticFriction ו-bounciness. השילוב של שני חומרים מאובייקטים במגע עוקב אחרי כללי frictionCombine ו-bounceCombine (Average, Minimum, Multiply, Maximum). לדמות על Rigidbody: PhysicMaterial עם dynamicFriction = 0, staticFriction = 0, frictionCombine = Minimum. בלי זה, הדמות מחליקה לאורך קירות, נתקעת בקצוות, ומאטה במפתיע על שיפועים. לאובייקטים קופצים: bounciness = 0.6, bounceCombine = Maximum. עם bounceCombine = Average, כדור שנזרק על משטח עם bounciness = 0 לא יקפוץ בכלל — גם אם לכדור עצמו יש ערך גבוה.
קוליידרים מורכבים ואופטימיזציה
אנחנו מתארים צורות מורכבות של אובייקטים באמצעות כמה קוליידרים פרימיטיביים על אובייקטי ילד — קוליידר מורכב (compound collider). Rigidbody אחד על ההורה שולט בכל היחידה הפיזיקלית. זה זול יותר מ-MeshCollider ומדויק יותר מ-BoxCollider יחיד. לרכבים: BoxColliders נפרדים לגוף, פגושים, קשתות גלגלים. WheelCollider הוא רכיב מיוחד להתנהגות מתלים ריאליסטית; הוא לא משתתף באירועי OnCollisionEnter רגילים.
מה כלול בהקמת פיזיקה במפתח מוכן
| שלב | פרטים |
|---|---|
| ביקורת על התצורה הנוכחית | ניתוח קוליידרים, Layer Matrix, PhysicMaterial וזיהוי התנגשות |
| עיצוב ויישום | הגדרת סוגי קוליידרים, קוליידרים מורכבים, חומרים פיזיקליים |
| אופטימיזציית ביצועים | כיוונון Layer Matrix, הפחתת קריאות ציור דרך batching, התאמת איטרציות פותר |
| בדיקות | אימות למנהור, יציבות פיזיקלית ב-FPS שונים |
| תיעוד והדרכה | תיאור ארכיטקטורה, המלצות להמשך פיתוח |
בפרויקט עדכני אחד, תיקנו דמות שנפלה כל הזמן דרך רצפות במהירויות מעל 10 מ'/ש'. שורש הבעיה היה MeshCollider לא קמור על הסביבה וזיהוי בדיד על הדמות. החלפנו את ה-MeshCollider בסט של BoxColliders פרימיטיביים שיוצרים קוליידר מורכב, הגדרנו את ה-Rigidbody של הדמות ל-Continuous, וכיווננו את ה-Layer Matrix כדי להוציא אזורי טריגר מפגיעות raycast. אחרי התיקון, הדמות מעולם לא נפלה דרך, ועומס המעבד עלה רק ב-3%.
הערכות זמנים (מחיר מצוטט לאחר ניתוח)
| משימה | זמן |
|---|---|
| הגדרת קוליידר דמות בסיסי + Layer Matrix | 1–2 ימים |
| פיזיקת רכב (WheelCollider, מתלים) | 3–7 ימים |
| מערכת אובייקטים ניתנים להריסה (רשתות שבורות + Rigidbody) | 1–2 שבועות |
| פותר פיזיקה מותאם אישית (בלי PhysX) | 4–8 שבועות |
טעויות אופייניות ואיך להימנע מהן
הקוליידר חורג מהרשת של הרנדר — הדמות עוברת ויזואלית דרך קיר אבל פיזית פוגעת במחסום בלתי נראה. ודאו שמידות הקוליידר תואמות לרשת. OnCollisionEnter לא נקרא — אחד האובייקטים הוא Rigidbody קינמטי או StaticCollider בלי Rigidbody. OnCollisionEnter דורש Rigidbody על לפחות אובייקט אחד. לגיאומטריה סטטית, OnTriggerEnter על אזורי טריגר מספיק. אובייקטים פיזיקליים רועדים במקום — מספר איטרציות הפותר נמוך מדי או שהאובייקט תחת כוחות מתחרים. הגדילו את Default Solver Iterations מ-6 ל-10–12 לסצנות מורכבות.
המהנדסים שלנו עם שנים של ניסיון יכולים לעזור לכם להימנע מהמלכודות האלה. הזמינו הקמת פיזיקה — קבלו ייעוץ ופתרון מוכן.





