Menu
CoddyTech

מהר יותר ויותר

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

רץ אינסופי נשאר מותח כי הוא נעשה קשה יותר ויותר. עקוב אחר משך הריצה, ותן למהירות לגדול יחד איתו, עד למהירות מרבית:

runTime += Time.deltaTime;
speed = Mathf.Min(maxSpeed, startSpeed + speedUp * runTime);

החל מ־10, המהירות גדלה ב־0.25 לשנייה ומגיעה ל־24 אחרי 56 שניות. המהירות המרבית אינה קשורה רק לרמת הקושי: במהירות של 24 יחידות לשנייה, הדרך נעה 0.4 יחידות בכל פריים, עדיין פחות מרוחב הרץ, ולכן הוא לעולם לא יוכל לעבור דרך מכשול בין שני פריימים.

challenge icon

אתגר

קל
  1. ב־GameManager הוסף את public float maxSpeed = 24f;, את public float speedUp = 0.25f; ואת public float runTime;.
  2. ב־Update, לפני חישוב המרחק, הגדל את runTime והגדר את המהירות כפי שתואר למעלה.

נסו בעצמכם

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 float magnetTime = 8f;

    public int lane;
    public float magnet;
    public bool shield;

    private CharacterController controller;
    private GameManager game;
    private Renderer body;
    private float fallSpeed;
    private float slide;
    private Color color;

    void Start()
    {
        controller = GetComponent<CharacterController>();
        game = FindFirstObjectByType<GameManager>();
        body = GetComponent<Renderer>();
        color = body.material.color;
    }

    void Update()
    {
        if (!game.over)
        {
            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 (magnet > 0f) magnet -= Time.deltaTime;

        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);

        body.material.color = shield ? new Color(0.3f, 0.9f, 1f) : color;
        ShowPower();
    }

    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;
    }

    void ShowPower()
    {
        string text = "";
        if (magnet > 0f) text = "Magnet " + Mathf.CeilToInt(magnet);
        if (shield) text += (text == "" ? "" : "   ") + "Shield";
        game.powerText.text = text == "" ? " " : text;
    }

    void OnTriggerEnter(Collider other)
    {
        if (game.over) return;
        if (other.CompareTag("Obstacle"))
        {
            if (shield)
            {
                shield = false;
                Destroy(other.gameObject);
                return;
            }
            game.GameOver();
        }
        else if (other.CompareTag("Coin"))
        {
            game.AddCoin();
            Destroy(other.gameObject);
        }
        else if (other.CompareTag("Magnet"))
        {
            magnet = magnetTime;
            Destroy(other.gameObject);
        }
        else if (other.CompareTag("Shield"))
        {
            shield = true;
            Destroy(other.gameObject);
        }
    }
}

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

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