FixedUpdate לפיזיקה
חלק מהיחידה פיזיקה ומשחקיות במסלול ה-Unity של Coddy. שיעור 4 מתוך 63.
Unity מזיזה גופים בצעדי פיזיקה קבועים של 0.02 שניות (Time.fixedDeltaTime), 50 פעמים בשנייה, ללא קשר לקצב הפריימים. FixedUpdate() פועלת ממש לפני כל צעד. Update() פועלת פעם אחת בכל פריים שמצויר, וזה יכול להיות 30, 60 או 144 פעמים בשנייה: בקצב של 144, ברוב הפריימים אין בכלל צעד פיזיקה, ובמחשב איטי פריים אחד יכול להכיל שני צעדים.
מכאן נובעים שני כללים. כוח שמוסיפים ב־Update() מתווסף פעם אחת בכל פריים, ולכן מחשב מהיר יותר דוחף חזק יותר: כוחות שפועלים לאורך זמן מוסיפים ב־FixedUpdate(). בנוסף, GetKeyDown הוא true למשך פריים אחד בלבד; אם בפריים הזה אין צעד פיזיקה, FixedUpdate() לא תזהה אותו והלחיצה תאבד. לכן קוראים את הלחיצות ב־Update(), שומרים אותן במשתנה מסוג bool, ומבצעים את הפעולות בעקבותיהן ב־FixedUpdate(). הסירה הזאת נדחפת ברוח קבועה ומזנקת הצידה בלחיצה:
private bool dashQueued;
void Update()
{
if (Input.GetMouseButtonDown(0))
{
dashQueued = true; // זכור את הלחיצה
}
}
void FixedUpdate()
{
rb.AddForce(Vector3.forward * wind); // דחיפה קבועה, בכל צעד
if (dashQueued)
{
rb.AddForce(Vector3.right * 4f, ForceMode.Impulse);
dashQueued = false; // לחיצה אחת, זינוק אחד
}
}חשוב לאפס את המשתנה הבוליאני אחרי שמשתמשים בו: אם משאירים אותו על true, הסירה תזנק בכל צעד. אפשר גם להוסיף דחיפה רגעית יחידה ישירות מתוך Update(), כפי שנעשה בקפיצה של הצפרדע; המשתנה הבוליאני מרכז את כל הדחיפות במקום אחד, לצד הכוחות שהוא עובד איתם. מקשים שמוחזקים לחוצים (GetKey, GetAxis) מתארים מצב ולא רגע מסוים, ולכן FixedUpdate() יכולה לקרוא אותם ישירות. בתוך FixedUpdate(), הערך של Time.deltaTime הוא 0.02, משך הצעד.
אתגר
קללמזחלת שעל האגם הקפוא יש שתי פעולות שמתבצעות במתודה הלא נכונה. המקשים שמאלה וימינה דוחפים אותה בתוך Update(), ולכן היא נדחפת חזק יותר במחשבים מהירים יותר. לחיצה על מקש הרווח מקפיצה אותה באמצעות דחף בתוך FixedUpdate(), ולכן חלק מהלחיצות אינן עושות דבר.
- העבר את הדחיפה באמצעות המקשים שמאלה וימינה לתוך
FixedUpdate(). - קרא את מקש הרווח בתוך
Update()למשתנה מסוגboolבשםhopPressed; בתוךFixedUpdate(), בצע קפיצה כשהוא מוגדר, ואז אפס אותו.
לחץ על Play ונסה את שניהם, ואז לחץ על Check.
נסו בעצמכם
using UnityEngine;
public class Sled : MonoBehaviour
{
public float push = 6f;
public float hop = 5f;
private Rigidbody rb;
void Start()
{
rb = GetComponent<Rigidbody>();
}
void Update()
{
if (Input.GetKey(KeyCode.RightArrow))
{
rb.AddForce(Vector3.right * push);
}
if (Input.GetKey(KeyCode.LeftArrow))
{
rb.AddForce(Vector3.left * push);
}
}
void FixedUpdate()
{
if (Input.GetKeyDown(KeyCode.Space))
{
rb.AddForce(Vector3.up * hop, ForceMode.Impulse);
}
}
}
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה פיזיקה ומשחקיות
1גוף קשיח
כוח הכבידה והמסהדחיפה באמצעות AddForceקפיצה באמצעות מתקףFixedUpdate לפיזיקהמהירותגופים קינמטייםחזרה: משטח שיגור2התנגשויות
OnCollisionEnterבמה פגעתי?להישבר בעת פגיעהלעמוד על הקרקעניתור וחיכוךצורות Colliderסיכום: קיר שביר5פרויקט: מרוץ המטבעות
הכדור המתגלגלמטבעות לאיסוף