Menu
CoddyTech

הוספת כוח הכבידה באופן ידני

חלק מהיחידה בניית משחקים אמיתיים במסלול ה-Unity של Coddy. שיעור 39 מתוך 60.

רכיב מסוג CharacterController נופל רק אם הסקריפט שלך גורם לו ליפול, ונפילה אמיתית מואצת: כוח הכבידה מוסיף למהירות הנפילה בערך 9.81 יחידות בשנייה, בכל שנייה. לכן הסקריפט שומר את המהירות האנכית בשדה, מוסיף לה gravity * Time.deltaTime בכל פריים, ומבצע תנועה לפיה באותה פקודת Move שבה מתבצעת ההליכה:

public float gravity = -9.81f;
float verticalSpeed;

void Update()
{
    if (controller.isGrounded && verticalSpeed < 0f)
    {
        verticalSpeed = -2f;   // על הקרקע: עצור את הנפילה, שמור על דחיפה קלה כלפי מטה
    }
    verticalSpeed += gravity * Time.deltaTime;

    Vector3 move = new Vector3(Input.GetAxisRaw("Horizontal"), 0f, Input.GetAxisRaw("Vertical")) * speed;
    move.y = verticalSpeed;
    controller.Move(move * Time.deltaTime);
}

Time.deltaTime מופיע פעמיים, לשתי מטרות: gravity * Time.deltaTime היא המהירות שנוספה בפריים הזה, והמהירות כפול Time.deltaTime היא המרחק שעוברים בפריים הזה. המהירות נשמרת בשדה, כי היא צריכה להישמר מפריים לפריים; משתנה מקומי היה מתחיל שוב ב-0 בכל פריים. בנפילה ממנוחה, מהירות הרכיב היא ‎-4.9 יחידות בשנייה אחרי חצי שנייה, ו-‎-9.81 אחרי שנייה.

האיפוס חשוב לא פחות מהנפילה. על הרצפה, Move עוצר את הרכיב, אבל שום דבר לא עוצר את השדה: בלי האיפוס הוא ממשיך לגדול בזמן שהשחקן עומד, והצעד הבא מעבר לקצה יגרום לנפילה במהירות מלאה. מאפסים אותו למספר שלילי קטן ולא ל-0, כדי שכל פקודת Move עדיין תלחץ לכיוון הרצפה: בקצב פריימים גבוה, הדחיפה של כוח הכבידה בפריים יחיד עשויה להיות קצרה מ-Min Move Distance, פקודת Move לא תעשה דבר ו-isGrounded יהפוך ל-false. קוראים את isGrounded לפני פקודת Move, ולכן הוא מתאר את פקודת Move של הפריים הקודם.

challenge icon

אתגר

בינוני

הענק לצולל כוח משיכה, כדי שמהירות הנפילה שלו תגבר.

  1. בתחילת Update(), כאשר controller.isGrounded וגם verticalSpeed < 0f, הגדר verticalSpeed = -1f;.
  2. הוסף לו את gravity * Time.deltaTime, והשאר אותו ב--maxFall או מעליו באמצעות Mathf.Max.
  3. לפני שורת controller.Move, הגדר move.y = verticalSpeed;.

לחץ על "שחק" ולך אל מחוץ למגדל: מהירות הנפילה תגבר עד ל-10 יחידות בשנייה. לאחר מכן לחץ על "בדיקה".

נסו בעצמכם

using UnityEngine;

public class Diver : MonoBehaviour
{
    public float speed = 4f;
    public float gravity = -12f;
    public float maxFall = 10f;

    CharacterController controller;
    float verticalSpeed;

    void Start()
    {
        controller = GetComponent<CharacterController>();
    }

    void Update()
    {
        // כבידה: אפס את verticalSpeed כשהדמות על הקרקע, הוסף את כוח הכבידה, הגבל את מהירות הנפילה והכנס את הערך ל-move.y

        Vector3 move = new Vector3(Input.GetAxisRaw("Horizontal"), 0f, Input.GetAxisRaw("Vertical")) * speed;
        controller.Move(move * Time.deltaTime);
    }
}

כל השיעורים ביחידה בניית משחקים אמיתיים

תרגלו בעצמכם: Unity אונליין