Menu
CoddyTech

Jamais à plat

Leçon 10 sur 16 du cours Jeu Unity : casse-briques de Coddy.

Une balle peut finir par voler presque à l’horizontale : un rebond sur le coin d’une brique ou une poussée d’une autre balle peut la laisser presque à niveau, traversant le terrain encore et encore sans redescendre. Le jeu est bloqué pendant que le joueur attend qu’elle redescende. La correction se fait dans la correction de la vitesse : après avoir donné à la direction une longueur de 1 unité, si sa composante y est trop petite, définis y à une valeur minimale et normalise à nouveau.

Deux méthodes Mathf font le travail. Mathf.Abs donne la valeur absolue d’un nombre, sans son signe, de sorte qu’un seul test détecte les balles qui montent et celles qui descendent. Mathf.Sign donne -1 pour un nombre négatif et 1 sinon, de sorte que le nouveau y conserve le sens de la balle : une balle qui descend continue de descendre.

float drift = -0.12f;
Debug.Log(Mathf.Abs(drift));    // 0.12
Debug.Log(Mathf.Sign(drift));   // -1

Fais le calcul avec une valeur minimale de 0.3 et la direction (0.99, -0.12, 0). La valeur absolue de y, 0.12, est inférieure à 0.3, donc y devient -0.3, et la normalisation de (0.99, -0.3, 0) donne environ (0.96, -0.29, 0) : la balle va toujours vers la droite et vers le bas, maintenant avec une pente suffisante pour revenir. La normalisation ramène y légèrement sous la valeur minimale, et l’étape suivante le remonte, de sorte qu’il reste légèrement inférieur à 0.3. Les directions plus abruptes restent inchangées.

challenge icon

Défi

Moyen
  1. Ajoute public float minVertical = 0.3f à Ball.
  2. Dans FixedUpdate(), récupère la direction : la vélocité normalisée. Si la valeur absolue de sa composante y est inférieure à minVertical, définis y à minVertical en conservant son signe, puis normalise à nouveau la direction.
  3. Ensuite, définis la vélocité comme étant la direction multipliée par speed, comme précédemment.

Appuie sur Play, puis sur Check.

Essayez vous-même

using UnityEngine;
using UnityEngine.InputSystem;

public class Ball : MonoBehaviour
{
    public Transform paddle;
    public float speed = 9f;

    Rigidbody rb;
    bool launched;

    void Awake()
    {
        rb = GetComponent<Rigidbody>();
        PhysicsMaterial bouncy = new PhysicsMaterial("Bouncy");
        bouncy.bounciness = 1f;
        bouncy.dynamicFriction = 0f;
        bouncy.staticFriction = 0f;
        bouncy.bounceCombine = PhysicsMaterialCombine.Maximum;
        bouncy.frictionCombine = PhysicsMaterialCombine.Minimum;
        GetComponent<Collider>().material = bouncy;
    }

    void Update()
    {
        if (launched) return;
        transform.position = paddle.position + Vector3.up * 0.5f;
        if (Keyboard.current.spaceKey.wasPressedThisFrame) Launch(new Vector3(0.3f, 1f, 0f));
    }

    public void Launch(Vector3 direction)
    {
        launched = true;
        rb.linearVelocity = direction.normalized * speed;
    }

    public void ResetToPaddle()
    {
        launched = false;
        rb.linearVelocity = Vector3.zero;
    }

    void FixedUpdate()
    {
        if (!launched) return;
        rb.linearVelocity = rb.linearVelocity.normalized * speed;
    }

    void OnCollisionEnter(Collision collision)
    {
        if (!collision.gameObject.CompareTag("Paddle")) return;
        float offset = transform.position.x - collision.transform.position.x;
        float halfWidth = collision.collider.bounds.size.x / 2f;
        float x = Mathf.Clamp(offset / halfWidth, -1f, 1f);
        rb.linearVelocity = new Vector3(x, 1f, 0f).normalized * speed;
    }

    void OnTriggerEnter(Collider other)
    {
        if (other.CompareTag("DeathZone")) GameManager.Instance.BallLost(this);
    }
}
quiz iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

Toutes les leçons de Jeu Unity : casse-briques