Menu
CoddyTech

Obstacles

Leçon 9 sur 20 du cours Jeu Unity : Voies célestes de Coddy.

La route a maintenant besoin d’un élément à éviter. Chaque morceau reçoit un obstacle au milieu, dans une voie choisie au hasard. Une méthode s’en charge : Fill, appelée pour chaque nouveau morceau dans Start, puis à chaque fois qu’un morceau revient à l’avant.

Les deux premiers morceaux restent vides, pour laisser un instant au joueur : Road compte les morceaux qu’il a remplis dans 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) donne -1, 0 ou 1 : avec des nombres entiers, le second nombre n’est jamais choisi.

Un morceau recyclé conserve son ancien obstacle. Clear détruit chaque enfant qui possède une balise. Le sol, les tirets et les bords sont Untagged, ils restent donc en place :

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

Défi

Facile
  1. Dans Road, ajoute public GameObject barrierPrefab;, public int safeChunks = 2; et private int made;.
  2. Écris Place(chunk, prefab, lane, y, z) : cette méthode crée le prefab à chunk.position + new Vector3(lane * laneWidth, y, z) avec prefab.transform.rotation, en tant qu’enfant du morceau.
  3. Écris Fill et Clear comme ci-dessus.
  4. Appelle Fill(chunk) pour chaque morceau dans Start, et Clear(chunk); Fill(chunk); lorsqu’un morceau passe à l’avant.

Essayez vous-même

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

Toutes les leçons de Jeu Unity : Voies célestes

Entraînez-vous par vous-même : Playground Unity