Menu
CoddyTech

Rester au sol

Fait partie de la section Physique et gameplay du Journey Unity de Coddy. Leçon 11 sur 71.

Chaque contact a une normale : une direction de longueur 1, perpendiculaire à la surface que tu as touchée et orientée de celle-ci vers ton objet. collision.GetContact(0) correspond au premier point de contact, et sa normal t’indique quel côté tu as touché. Sur un sol plat, elle vaut (0, 1, 0) ; contre un mur à ta droite, (-1, 0, 0) ; lorsque tu te cognes la tête au plafond, (0, -1, 0).

Cette caisse distingue les atterrissages des chocs latéraux :

void OnCollisionEnter(Collision collision)
{
    Vector3 normal = collision.GetContact(0).normal;
    if (normal.y > 0.5f)
    {
        Debug.Log("Landed on " + collision.gameObject.name);
    }
    else
    {
        Debug.Log("Bumped the side of " + collision.gameObject.name);
    }
}

Le test est normal.y > 0.5f plutôt que d’exiger exactement 1, afin que les pentes comptent aussi comme du sol : y vaut 0.5 sur une pente de 60 degrés, plus raide que ce que n’importe qui peut gravir à pied. Deux autres messages aident à gérer tout ce qui dure : OnCollisionStay s’exécute à chaque étape physique tant que le contact dure, et OnCollisionExit une fois lorsqu’il prend fin. Un événement de sortie n’a aucun point de contact, puisque plus rien ne se touche ; n’appelle donc pas GetContact à cet endroit.

challenge icon

Défi

Facile

Fais sauter le joueur uniquement lorsqu’il se trouve sur quelque chose.

  1. Ajoute private bool grounded;. Dans OnCollisionStay, définis-le à true lorsque collision.GetContact(0).normal.y > 0.5f ; dans OnCollisionExit, définis-le à false.
  2. Dans FixedUpdate(), fais sauter le joueur uniquement si if (jumpPressed && grounded), puis définis jumpPressed = false; après ce if, afin qu’une pression effectuée en l’air soit ignorée.

Appuie sur « Jouer » et essaie de faire un double saut : la deuxième pression ne fait rien. Puis appuie sur « Vérifier ».

Essayez vous-même

using UnityEngine;

public class Hopper : MonoBehaviour
{
    public float speed = 4f;
    public float jump = 6f;
    private Rigidbody rb;
    private bool jumpPressed;

    void Start()
    {
        rb = GetComponent<Rigidbody>();
    }

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            jumpPressed = true;
        }
    }

    void FixedUpdate()
    {
        float h = Input.GetAxisRaw("Horizontal");
        rb.linearVelocity = new Vector3(h * speed, rb.linearVelocity.y, 0);
        if (jumpPressed)
        {
            rb.AddForce(Vector3.up * jump, ForceMode.Impulse);
            jumpPressed = false;
        }
    }
}

Toutes les leçons de Physique et gameplay

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