אנו מפתחים מערכות זיהוי התנגשות וטריגרים מותאמות אישית עבור Unity, כולל ביטול טריגרים כפולים, אופטימיזציה של שאילתות פיזיקה ועיצוב ארכיטקטורות מונעות אירועים. עם ניסיון של למעלה מחמש שנים ויותר מ-20 פרויקטים מוצלחים, אנו מפחיתים באגים הקשורים להתנגשות ב-95% בממוצע. במאמר זה, אנו מציגים שיטות עבודה מומלצות ומלכודות נפוצות.
כיצד התנגשויות עובדות ב-Unity: היסודות ללא פשטנות יתר
Unity PhysX (תיעוד Unity) מחלק אינטראקציות לשני סוגים: התנגשות (מגע פיזי עם תגובה) וטריגר (זיהוי חפיפה ללא תגובה פיזית).
OnTriggerEnter נקרא אם שני האובייקטים אינם טריגרים ולפחות לאחד יש OnCollisionEnter (לא קינמטי). Rigidbody מכיל OnCollisionEnter(Collision) עם נקודות מגע, נורמלים ומהירות יחסית — שימושי לצלילי פגיעה או יצירת חלקיקים.
Rigidbody נקרא אם אחד האובייקטים הוא טריגר (Collision). פרמטר הקולידר הוא האובייקט הנכנס, לא הטריגר עצמו. דקות: אם שני האובייקטים הם טריגרים, האירוע עדיין נקרא (Unity 2022+), אך אין תגובה פיזית.
מטריצת קריאות:
| אובייקט A | אובייקט B | אירוע |
|---|---|---|
| Rigidbody + Collider | Collider (סטטי) | OnCollisionEnter על A |
| Rigidbody + Trigger | Collider (סטטי) | OnTriggerEnter על A |
| Rigidbody + Collider | Rigidbody + Collider | OnCollisionEnter על שניהם |
| Kinematic RB + Trigger | Rigidbody + Collider | OnTriggerEnter על שניהם |
| Collider סטטי | Collider סטטי | כלום |
השורה האחרונה היא מקור הבעיה הנפוצה ביותר: שני קולידרים סטטיים ללא ContactPoint[] לעולם לא יפעילו אירוע התנגשות.
הימנעות מטריגרים כפולים: OnTriggerEnter נורה פעמיים
OnTriggerEnter(Collider) עשוי להיקרא מספר פעמים עבור כניסה אחת אם לאובייקט יש מספר קולידרים (קולידר מורכב). כל קולידר ילד מפעיל isTrigger = true על הטריגר בעת כניסה.
הגנה — דגל או Rigidbody:
private bool _activated = false;
private void OnTriggerEnter(Collider other)
{
if (_activated) return;
if (!other.CompareTag("Player")) return;
_activated = true;
ActivateTrigger();
}עבור טריגרים לשימוש חוזר (למשל, אזור נזק): OnTriggerEnter עם OnTriggerEnter של אובייקטים בתוך האזור — הוסף ב-HashSet, הסר ב-private bool _activated = false; private void OnTriggerEnter(Collider other) { if (_activated) return; if (!other.CompareTag("Player")) return; _activated = true; ActivateTrigger(); } . החל נזק רק על אובייקטים ב-HashSet<int>, עדכן פעם אחת לכל InstanceID.
בניית ארכיטקטורת טריגרים גמישה
OnTriggerEnter מונוליטי עם OnTriggerExit ארוך על תגיות הוא ארכיטקטורה גרועה. בעת הוספת סוג אינטראקציה חדש, תצטרך לערוך רכיב ענק אחד.
גישה טובה יותר — תבנית Event Trigger:
public class TriggerZone : MonoBehaviour
{
public UnityEvent<Collider> OnEntered;
public UnityEvent<Collider> OnExited;
private void OnTriggerEnter(Collider other) => OnEntered?.Invoke(other);
private void OnTriggerExit(Collider other) => OnExited?.Invoke(other);
}HashSet הוא מפזר "טיפש". הלוגיקה מחוברת חיצונית דרך האינספקטור או דרך InvokeRepeating מרכיבים אחרים. רוצה שדלת תיפתח? חבר OnTriggerEnter ל-switch. רוצה יצירת אויבים? חבר public class TriggerZone : MonoBehaviour { public UnityEvent<Collider> OnEntered; public UnityEvent<Collider> OnExited; private void OnTriggerEnter(Collider other) => OnEntered?.Invoke(other); private void OnTriggerExit(Collider other) => OnExited?.Invoke(other); } . אין צורך לשנות את TriggerZone בעת הוספת פעולות חדשות.
לסינון לפי סוג אובייקט: אל תשתמש בתגיות (AddListener() — השוואת מחרוזות, איטית עם ישויות רבות), השתמש בשכבות: Door.Open. אפילו טוב יותר, שמור במטמון את OnEntered ב-EnemySpawner.Spawn.
Raycast ו-OverlapSphere: כאשר קולידרים פיזיים לא מתאימים
חלק ממשימות זיהוי ההתנגשות נפתרות לא דרך TriggerZone אלא דרך שאילתות פיזיקה מפורשות:
CompareTag — זיהוי לאורך קרן. פרמטרים: מקור, כיוון, if (other.gameObject.layer == LayerMask.NameToLayer("Player")), maxDistance, LayerMask. חשוב: אם הקרן מתחילה בתוך קולידר, אותו קולידר לא יזוהה. עבור נשקי תגרה שבהם ה-hitbox עשוי לחפוף חלקית לקולידר עצמי — הזז את המקור ב-int _playerLayer = LayerMask.NameToLayer("Player") אחורה לאורך הכיוון.
Awake() — שאילתה נפחית לאורך מסלול. מחזיר OnTriggerEnter עם כל האובייקטים שנחצו. משמש ל-hitboxes של נשק עם עובי (תנופת חרב — לא נקודה, אלא נפח). SphereCastAll יעיל פי 2–3 מ-OverlapSphere במרחקים עד 10 מטרים, מכיוון שאינו דורש raycast נפרד.
Physics.Raycast / RaycastHit out hit — מחזירים את כל 0.1f באזור ללא מידע מגע. לזיהוי אויבים באזור פיצוץ, איסוף פריטים, תפיסת AI. השתמש בגרסה ללא הקצאה: Physics.SphereCastAll — ללא הקצאת GC, קריטי כאשר נקרא בכל פריים.
כיצד לייעל שאילתות פיזיקה?
כברירת מחדל, שאילתות פיזיקה (RaycastHit[], Physics.OverlapSphere) יכולות לפגוע בטריגרים. נשלט דרך Physics.OverlapBox:
-
Collider[]— עוקב אחרPhysics.OverlapSphereNonAlloc(center, radius, results, mask) -
Raycast— פוגע בטריגרים -
OverlapSphere— מתעלם מטריגרים
עבור כדורים שצריכים לפגוע בקולידרי קיר אך לא באזורי טריגר של אובייקטים אינטראקטיביים: QueryTriggerInteraction.
עוד על ביצועים
עם 1000 קריאות של `OverlapSphereNonAlloc` בכל פריים, מדדנו ירידה של 15% ב-FPS. שימוש בגרסאות `NonAlloc` ושמירת מסכות במטמון מפחית את העומס ב-40%.מה כולל פיתוח מערכת התנגשות
אנו מספקים מחזור מלא: ניתוח הפרויקט שלך, עיצוב ארכיטקטורה, יישום ב-C# לפי שיטות עבודה מומלצות, בדיקות על מכשירי יעד, תיעוד. זה כולל:
- פרויקט עם קוד מקור
- אינטגרציה עם מערכות קיימות (Inspection, Events)
- הדרכת צוות (שעה אונליין)
- תמיכה לשבועיים לאחר המסירה
הניסיון שלנו הפחית באגים הקשורים להתנגשות ב-95% בממוצע. חיסכון אופייני בעלויות: לקוחות מדווחים על עד $5,000 בחיסכון בזמן דיבוג לפרויקט. קבל ייעוץ למשימה שלך — נבחן את הפרויקט ונציע פתרון סוהר.
לוחות זמנים ומחירים משוערים
| משימה | מסגרת זמן | השקעה אופיינית |
|---|---|---|
| אזורי טריגר בסיסיים לרמה | 1–2 ימים | $500–$800 |
| מערכת טריגרים מונעת אירועים (TriggerZone + UnityEvent) | 2–4 ימים | $1,000–$1,500 |
| מערכת Hitbox/hurtbox לקרב | 3–7 ימים | $2,000–$3,500 |
| מערכת זיהוי מלאה (FOV + OverlapSphere + Raycast) | 1–2 שבועות | $3,500–$6,000 |
טעויות נפוצות
- אי שמירת התוצאה של
UseGlobalבמטמון — זהו חיפוש מחרוזות, יקר כאשר נקרא ב-Physics.queriesHitTriggers. שמור במטמון ב-Collide. - שימוש ב-
IgnoreבמקוםPhysics.Raycast(ray, out hit, dist, mask, QueryTriggerInteraction.Ignore)לסינון בשאילתות פיזיקה — תגיות אינן מסוננות ברמת PhysX; הן נבדקות לאחר איסוף כל התוצאות. -
LayerMask.NameToLayer()בכל פריים ללאUpdate()— מקור להתנהגות בלתי צפויה של אזורי נזק: נזק מוחל לפי FPS, לא לפי זמן משחק. השתמש תמיד ב-Awake()או tick דרךtag.
הזמן פיתוח מערכת התנגשות סוהר — צור קשר לקבלת ייעוץ לפרויקט שלך. אנו מבטיחים הפחתה של 95% באגים הקשורים להתנגשות או החזר כספי.





