Le cambouis - Commençons par les oiseaux (1/3)

UnityUnity 3DtutorialC#
Julien LAPA - 09/01/2023 à 15:56:380 commentaire

Il est temps… de se mettre un peu à tâter l’outil. Si vous avez suivi nos deux derniers articles sur le moteur UNITY 3D, vous ne devriez pas être totalement étranger à l’interface qui vous attend.

Je vous propose donc de vous accompagner pas à pas afin de découvrir l’outil, ses différents composants et autres interactions. Let’s go pour faire un pseudo Flappy Bird !  

 

Un, peu de préparation

 

Créez un nouveau projet. Pour cet article, je suis en version 2017.3.0f0 pour utiliser la même version que les anciens articles, mais il devrait fonctionner sur n’importe quelle version.

 

Une fois le projet lancé, vous devriez être devant l’interface ci-dessus. Ouvrez une ligne de commande git et téléchargez les assets suivants dans un nouveau répertoire « sprites » : git clone https://github.com/samuelcust/flappy-bird-assets.

Nous devrions tout avoir pour réaliser cet article !

 

Le petit oiseau

 

Nous allons créer notre premier élément. Que serait un flappy bird sans un oiseau ? Observons un peu ce que doit être capable de faire l’oiseau :

  • Voler (ou plutôt battre des ailes)
  • Mourir si jamais il vient à toucher quelque chose
  • Gagner des points quand il passe un obstacle

 

Commençons donc par créer notre oiseau. Nous allons donc créer un nouvel objet 2D de type « Sprite ».




Voici à quoi devrait ressembler l’objet que vous venez de créer. Petite présentation de ce qu’il y a dans l’inspecteur :

  • Le nom du GameObjet que je vous invite à modifier et qui s’affichera autant dans l’inspecteur que la hiérarchie, que l’onglet Project.
  • La checkbox à gauche du nom, qui permet d’indiquer si GameObjet est actif ou non.
  • La checkbox static, qui ne nous sera d’aucune utilité pour notre sujet.
  • Le tag, que je vous invite à modifier en cliquant sur le petit onglet déroulant et l’ajoutant. Il sera très utile pour certains scripts à venir.
  • Le layer qui correspond à la couche physique dans laquelle se trouve le GameObjet. Elle sert notamment à préciser quels GameObjets peuvent interagir ensemble.
  • La liste des composants :
  • Le transform qui est le composant obligatoire de n’importe quel GameObject.
  • Le sprite renderer qui permet de modifier l’apparence de l’objet. Dans notre cas, il va falloir Drag&Drop le sprite de l’oiseau directement au niveau de l’attribut « Sprite » du composant.

Vous devriez désormais avoir le même résultat que la capture d’écran ci-dessus.

 

Commençons par le vol. L’oiseau doit être en mesure chuter et dans notre cas il faut que la gravité le rattrape. Pour ce faire, nous allons lui rajouter un composant essentiels et primordial d’Unity qui est un Rigidbody (Rigidbody2D dans notre cas). Nous allons également lui ajouter un autre composant qui est un CircleCollider2D et qui permettra de gérer les collisions.



Une fois configuré comme ci-dessus, l’oiseau devrait tomber si vous lancé la scène. Maintenant que la gravité rattrape notre oiseau, il est temps de créer notre premier script pour lui permettre de se battre contre elle.




Voici à quoi devrait ressembler le script. Petite présentation des éléments. Tout script dans Unity hérite de la classe MonoBehavior. C’est elle qui permet d’inclure tous les outils nécessaires pour interagir avec les autres composants, la scène, les autres objets etc… Il est possible de faire de la PO classique, notamment pour gérer les modèles de donnés ou pour créer des systèmes qui n’ont pas besoin d’être physiquement instanciés. Si vous avez besoin d’un objet physique, faites hériter votre classe de MonoBehavior.

Chaque script créé aura par défaut 2 méthodes qui sont des méthodes de base du cycle d’exécution. Start est appelé une fois à la première activation du script. Update est appelé une fois par frame. Une frame correspond à un instant d’exécution dans le temps. Il peut donc avoir plusieurs frames dans une seconde.

 

Maintenant que le script par défaut est présenté, alimentons-le :


using System.Collections;
using System.Collections.Generic;
using UnityEngine;


public class FlyLittleBird : MonoBehaviour
{

    [SerializeField]
    private float ForceIntensity;

    //private components and variables
    private Rigidbody2D _rb;


    void Start()
    {
        _rb = GetComponent<Rigidbody2D>();
    }


    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            _rb.velocity = Vector3.zero;
            _rb.AddForce(ForceIntensity * Vector3.up);
        }
    }
}



Dans la capture d’écran ci-dessus j’ai fait la chose suivante :

  • Créer une variable publique ForceIntensity qui va nous servir à configurer la force de la poussée du vol.
  • Créer une variable privée _rb de type Rigidbody2D.
  • Affecter à la variable _rb la récupération du composant Rigidbody2D.
  • Coder le comportement suivant. Au moment où la touche espace est enfoncée, j’exécute un ajout de force qui va correspondre à aller vers le haut (donc le vecteur 0,1,0) multiplié par la force voulue.

 

Petites précisions : Si nous affectectons le Rigidbody dans une variable, c’est que l’utilisation de la fonction GetComponent est relativement coûteuse en termes de ressource. Il est très facile d’avoir une dérive en termes de performance quand sont présents des centaines de scripts sur des centaines d’objets qui redemandent à chaque frame le même composant.

GetComponent est une fonction qui par défaut fait référence au GameObject courant. Il est possible de récupérer des composant d’autres objets à condition de pointer sur le bon GameObject.


En ajoutant le script au GameObject, nous remarquons que la variable ForceIntensity vient d’apparaître dans l’inspecteur et il nous est désormais possible de la modifier. Il ne faut pas oublier qu’Unity est avant tout un outil de collaboration entre différents métiers. Quand vous créez un jeu, il est logique que ce soit le développeur qui fasse les scripts mais c’est au Game Designer de venir décider de la puissance d'une poussée. Par défaut, toutes les variables publiques exposent dans l’inspecteur la possibilité de changer leur valeur sans avoir besoin de modifier le code. Seulement ici, votre âme de développeur doit tiquer sur l’accessibilité de la variable. Dans notre cas, aucun élément ne vient influer sur cette force. Il n’est donc pas normal d’avoir une variable publique. Nous allons remédier à ça en ajoutant l’attribut SerializeField et en passant la variable en privé. Il nous est désormais possible de modifier directement dans l’éditeur la valeur par défaut en ayant une accessibilité cohérente. Allons-y testons ce script d’envol !


 



 

Vous avez dû voir qu’il est assez compliqué de bien faire voler l’oiseau. Dans le cas où vous mettez une force trop importante, celui-ci met du temps à retomber et peux sortir de l’écran. Dans le cas où la force est trop faible, il faut marteler assez régulièrement la touche espace quand il ne faut pas la mitrailler parce que la chute est devenue trop rapide. Afin de régler ces petits désagréments je vous propose de nullifier la vitesse courante de l'oiseau à chaque impulsion. Cela permettra d’arrêter sa course et de donner une constance au mouvement. Pour le moment notre oiseau est bien. Il ne se déplace pas me direz-vous ? C’est normal. En réalité, les déplacements dans les jeux ne sont pas toujours ce que l’on pense. Pour avoir la sensation de se déplacer vers la droite, il faut soit que l’oiseau vole vers la droite, soit que les éléments et le décor se déplace vers la gauche.


Dans un runner, il est plus aisé de déplacer les éléments du décor vers la gauche que de faire bouger votre personnage vers la droite. Les points d’apparition (spawner) sont plus simples à manipuler lorsqu'ils restent immobiles. Cela permet également sur des cycles longs d’avoir des positions qui restent proches du centre du monde et éviter l’instanciation d’éléments trop distants.


Il reste encore des modifications à opérer sur l'oiseau, mais nous commençons à avoir un rendu sympathique. Je vous donne rendez-vous bientôt pour la suite de la découverte avec la création des obstacles et leur gestion !

 

Commentaires :

Aucun commentaires pour le moment


Laissez un commentaire :

Réalisé par
Expaceo