Menu
CoddyTech

מכשולים

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

עכשיו הכביש צריך משהו להתחמק ממנו. בכל חלק מופיע מכשול באמצע, בנתיב אקראי. מתודה עושה את זה, Fill, שנקראת עבור כל חלק חדש ב־Start ושוב בכל פעם שחלק חוזר לקדמת הכביש.

שני החלקים הראשונים נשארים ריקים, כדי לתת לשחקן רגע: הכביש סופר את החלקים שמילא ב־made.

void Fill(Transform chunk)
{
    made++;
    if (made <= safeChunks) return;

    int lane = Random.Range(-1, 2);
    Place(chunk, barrierPrefab, lane, 0.5f, 0f);
}

Random.Range(-1, 2) הוא ‎-1, 0 או 1: כשמשתמשים במספרים שלמים, המספר השני לעולם לא נבחר.

חלק שמוחזר לשימוש עדיין נושא את המכשול הישן שלו. Clear משמידה כל ילד שיש לו תג. לרצפה, למקפים ולקצוות אין תג, ולכן הם נשארים:

void Clear(Transform chunk)
{
    foreach (Transform child in chunk)
    {
        if (!child.CompareTag("Untagged")) Destroy(child.gameObject);
    }
}
challenge icon

אתגר

קל
  1. ב-Road הוסף את public GameObject barrierPrefab;, את public int safeChunks = 2; ואת private int made;.
  2. כתוב את Place(chunk, prefab, lane, y, z): היא יוצרת את ה-prefab במיקום chunk.position + new Vector3(lane * laneWidth, y, z) עם הסיבוב prefab.transform.rotation, כילד של המקטע.
  3. כתוב את Fill ואת Clear כמו למעלה.
  4. קרא ל-Fill(chunk) עבור כל מקטע ב-Start, ול-Clear(chunk); Fill(chunk); כשהמקטע עובר לחזית.

נסו בעצמכם

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 אונליין