שמירה על המהירות
שיעור 3 מתוך 16 בקורס משחק Unity: שובר לבנים של Coddy.
כדור של Brick Breaker אף פעם לא מאט. ה-PhysicsMaterial שלו עושה את רוב העבודה: מקדם הקפיציות 1 שומר על כל המהירות של הקפיצה, וחיכוך 0 מונע מהקירות לגרור את הכדור או לסובב אותו. לקירות וללבנים אין חומר משלהם, ו-Unity משלבת את הערכים של שני ה-Collider-ים, כברירת מחדל באמצעות Average: הערך 1 של הכדור וערך ברירת המחדל 0 של הקיר גורמים לקפיצה בחצי מהמהירות. הערכים bounceCombine = Maximum ו-frictionCombine = Minimum מאפשרים לערכים של הכדור עצמו לגבור על כל דבר שהוא פוגע בו.
הפיזיקה עדיין אינה מדויקת לחלוטין: משוט שנע מוסיף את המהירות שלו לקפיצה, שני כדורים דוחפים זה את זה, ושגיאות קטנות מצטברות לאורך מאות קפיצות. לכן, בכל FixedUpdate הכדור שומר על הכיוון שלו והמהירות שלו נקבעת מחדש. גם האפשרות Freeze Position Z מסומנת ב-Inspector עבור ה-Rigidbody של הכדור, וכך הוא נשאר במישור המשחק.
משחק אחר מצריך כלל אחר. דיסקית הוקי אוויר עשויה להאט, אך לעולם לא לעבור מהירות מרבית, ו-Vector3.ClampMagnitude מקצרת וקטור ארוך מדי ומשאירה וקטור קצר יותר ללא שינוי:
void FixedUpdate()
{
rb.linearVelocity = Vector3.ClampMagnitude(rb.linearVelocity, maxSpeed);
}הגבלת מהירות מרבית אינה מספיקה עבור הכדור: אם מהירותו תואט ל-2 יחידות בשנייה, הוא יישאר במהירות 2. יש לקבוע את המהירות שלו בדיוק, לפי הכיוון שלו.
אתגר
קלב־Ball:
- ב־
Awake(), צורnew PhysicsMaterial("Bouncy")עם מקדם החזר 1, חיכוך דינמי וסטטי 0,bounceCombineבערך Maximum ו־frictionCombineבערך Minimum, והקצה אותו לקוליידר של הכדור באמצעותGetComponent<Collider>().material. - הוסף
FixedUpdate(): כשהכדור שוגר, הגדר אתlinearVelocityשלו לכיוון הנוכחי שלו כפולspeed.
ב־Unity אפשר גם ליצור את החומר כנכס (Create > Physics Material) ולגרור אותו אל משבצת Material של Sphere Collider; כאן הסקריפט יוצר אותו.
לחץ על Play, שגר את הכדור וצפה בו קופץ, ואז לחץ על Check.
נסו בעצמכם
using UnityEngine;
using UnityEngine.InputSystem;
public class Ball : MonoBehaviour
{
public Transform paddle;
public float speed = 9f;
Rigidbody rb;
bool launched;
void Awake()
{
rb = GetComponent<Rigidbody>();
}
void Update()
{
if (launched) return;
transform.position = paddle.position + Vector3.up * 0.5f;
if (Keyboard.current.spaceKey.wasPressedThisFrame) Launch(new Vector3(0.3f, 1f, 0f));
}
public void Launch(Vector3 direction)
{
launched = true;
rb.linearVelocity = direction.normalized * speed;
}
}
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.