Menu
CoddyTech

התנגשות

שיעור 11 מתוך 20 בקורס משחק Unity: נתיבי שמיים של Coddy.

המכשולים הם מפעילים: הם מזהים את הרץ בלי לדחוף אותו. כאשר ה־CharacterController של הרץ ומפעיל נפגשים, Unity קוראת ל־OnTriggerEnter בסקריפטים של הרץ, עם המתנגש של המפעיל:

void OnTriggerEnter(Collider other)
{
    if (game.over) return;
    if (other.CompareTag("Obstacle"))
    {
        game.GameOver();
    }
}

GameOver מסיימת את הריצה: over הופך ל־true, המהירות יורדת ל־0 כך שהדרך נעצרת, וההודעה באמצע המסך מציגה זאת. כל עוד over הוא true, GameManager מפסיק לספור את המרחק וה־Runner מפסיק לקרוא את המקשים.

challenge icon

אתגר

בינוני
  1. ב־GameManager הוסף public TMP_Text messageText; ו־public bool over;.
  2. הוסף public void GameOver(): אם כבר over, החזר; אחרת הגדר over = true, speed = 0f ו־messageText.text = "Game over".
  3. בתחילת Update של GameManager, הוסף if (over) return;.
  4. ב־Runner, מצא את GameManager בתוך Start, קרא את המקשים רק כאשר !game.over, והוסף את OnTriggerEnter כפי שמופיע למעלה.

נסו בעצמכם

using UnityEngine;

public class Runner : MonoBehaviour
{
    public float laneWidth = 2.5f;
    public float laneSpeed = 16f;
    public float jumpHeight = 1.6f;
    public float gravity = -40f;
    public float slideTime = 0.7f;

    public int lane;

    private CharacterController controller;
    private float fallSpeed;
    private float slide;

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

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.A) || Input.GetKeyDown(KeyCode.LeftArrow)) lane = Mathf.Max(-1, lane - 1);
        if (Input.GetKeyDown(KeyCode.D) || Input.GetKeyDown(KeyCode.RightArrow)) lane = Mathf.Min(1, lane + 1);
        bool jump = Input.GetKeyDown(KeyCode.W) || Input.GetKeyDown(KeyCode.UpArrow) || Input.GetKeyDown(KeyCode.Space);
        if (jump && controller.isGrounded)
        {
            fallSpeed = Mathf.Sqrt(jumpHeight * -2f * gravity);
            StopSlide();
        }
        if ((Input.GetKeyDown(KeyCode.S) || Input.GetKeyDown(KeyCode.DownArrow)) && controller.isGrounded)
        {
            slide = slideTime;
            Resize(0.5f);
        }

        if (slide > 0f)
        {
            slide -= Time.deltaTime;
            if (slide <= 0f) StopSlide();
        }

        if (controller.isGrounded && fallSpeed < 0f) fallSpeed = -2f;
        fallSpeed += gravity * Time.deltaTime;

        float targetX = lane * laneWidth;
        float x = Mathf.MoveTowards(transform.position.x, targetX, laneSpeed * Time.deltaTime);
        Vector3 move = new Vector3(x - transform.position.x, fallSpeed * Time.deltaTime, 0f);
        controller.Move(move);
    }

    void StopSlide()
    {
        if (transform.localScale.y < 1f) Resize(1f);
        slide = 0f;
    }

    void Resize(float height)
    {
        controller.enabled = false;
        transform.position += Vector3.up * (height - transform.localScale.y);
        transform.localScale = new Vector3(1f, height, 1f);
        controller.enabled = true;
    }
}

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

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