Menu
CoddyTech

Pousser des objets

Fait partie de la section Créer de vrais jeux du Journey Unity de Coddy. Leçon 41 sur 60.

Un CharacterController ne pousse jamais rien : fais-le marcher contre une caisse avec un Rigidbody et il s’arrête comme devant un mur. À la place, Unity appelle OnControllerColliderHit(ControllerColliderHit hit) dans les propres scripts du contrôleur pour chaque collider touché par un Move, y compris le sol, et le script décide de ce qui se passe. hit.collider est ce qui a été touché, hit.moveDirection est la direction du Move qui l’a touché, et hit.normal est la direction vers laquelle sa surface est orientée au point de contact. Voici le script de poussée de Unity :

public float pushPower = 2f;

void OnControllerColliderHit(ControllerColliderHit hit)
{
    Rigidbody body = hit.collider.attachedRigidbody;
    if (body == null || body.isKinematic) return;   // rien à pousser
    if (hit.moveDirection.y < -0.3f) return;        // il est sous nos pieds

    Vector3 pushDir = new Vector3(hit.moveDirection.x, 0f, hit.moveDirection.z);
    body.linearVelocity = pushDir * pushPower;
}

Chaque return a une raison. Le sol et les murs n’ont pas de Rigidbody, donc body est null pour eux, et ils sont touchés lors de presque chaque Move. Un corps cinématique ne bouge que lorsque son propre script le déplace, donc une vitesse ne lui fait rien. Un Move orienté fortement vers le bas a touché quelque chose sous les pieds, et la caisse sur laquelle se tient le joueur ne devrait pas être poussée.

La direction de poussée ne conserve que x et z, ainsi la caisse glisse sur le sol au lieu d’être enfoncée dedans. Définir linearVelocity, plutôt que d’ajouter une force, déplace une caisse légère et une caisse lourde à la même vitesse ; body.AddForce(pushDir * pushPower, ForceMode.Impulse) pousserait moins la caisse lourde.

challenge icon

Défi

Moyen

Fais en sorte que le joueur donne un coup de pied aux balles qu’il heurte en marchant.

  1. Dans Kicker.cs, écris void OnControllerColliderHit(ControllerColliderHit hit) et récupère Rigidbody body = hit.collider.attachedRigidbody;.
  2. Utilise return lorsque body est null ou cinématique, ou lorsque hit.moveDirection.y < -0.3f (une balle sous les pieds).
  3. Définis body.linearVelocity selon la direction de marche avec y à 0, multipliée par kickPower, plus Vector3.up * lift.

Appuie sur « Jouer » et marche contre la balle rouge : elle s’envole vers l’avant et vers le haut. Puis appuie sur « Vérifier ».

Essayez vous-même

using UnityEngine;

public class Kicker : MonoBehaviour
{
    public float kickPower = 6f;
    public float lift = 4f;

    // Donner un coup de pied aux ballons que le joueur touche en marchant
}

Toutes les leçons de Créer de vrais jeux

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