PARTIE IV: Croissance

Au cours des précédentes parties, nous avons pu voir qu’il était possible, a partir de quelques règles géométriques simples, d’obtenir des structures assez complexes. Nous avons pu mettre en oeuvre un modèle de plante avec le moteur Unity.

Le problème auquel nous allons nous intéresser maintenant, c’est celui de simuler une croissance progressive de ces structures: en effet, jusqu’ici, nos plantes « poussent » de façon quasi instantanée. Nous allons remédier à cela, en enrichissant notre modèle, par l’introduction de la notion de temps: les plantes et les organes vont avoir leur propre horloge interne. Cette horloge va être utilisée pour donner un rythme à la croissance.

Croissance progressive

Pour intégrer la notion de temps dans le modèle de l’organe, nos allons ajouter un compteur qui augmente de façon continue avec le temps (simulé ou réel), son age en quelque sorte.

La taille de chaque organe est initialement fixée à 0,  et va augmenter progressivement, avec l’age de l’organe. La fonction pour calculer la taille va dépendre des paramètres suivants:

  • une vitesse d’élongation: c’est le coefficient appliqué à l’age de l’organe pour calculer sa taille
  • Une taille maximale, comprise entre 0 et 1. Ce paramètre permet essentiellement de diminuer la taille des organes le long des tiges.
  • le temps avant la création d’un nouvel élément: Un organe ne peut pas produire d’élément avant un certain temps. Permet de temporiser la production de nouvel organe.
  • le temps avant de démarrer la croissance: permet de légèrement désynchroniser les différents organes, pour qu’ils n’apparaissent pas tous en même temps.

Dans la classe, nous ajoutons donc les membres suivants:

[snippet id= »110″]

Dans la méthode Start(), la variable lifeCounter est initialisée de la sorte:

[snippet id= »116″]

Il faudra aussi modifier la méthode addOrgan pour que l’organe ait une taille initiale nulle, et copier ces nouveaux paramètres (hormis le lifeCounter) dans chaque nouvel organe créé.

[snippet id= »118″]

La fonction Update, enfin, contient le code qui permet de fixer la taille de l’organe en fonction du temps:

[snippet id= »115″]

A la ligne 11, le test original est modifié pour tenir compte du délai avant création de nouveaux organes.  La suite du code reste inchangée.

En l’état, le code fonctionne, mais pour explorer différentes configurations, pourquoi ne pas ajouter ces quelques lignes dans la fonction de mutation:

[snippet id= »113″]

Voila! normalement, les plantes peuvent désormais de façon progressive. Selon les paramètres, la croissance pourra être plus ou moins rapide, plus ou moins synchrone, etc. A vous d’ajouter d’autres lois pour changer la taille des organes (par exemple, quelque chose de plus cartoonesque, avec un effet de rebond, etc.).

Le code a ce stade est disponible ici.  Cette partie est en effet décomposée en 3 étapes principales, il reste donc encore deux autres archives.

Explosion du nombre d’éléments

Si vous avez procédé à des modifications dans les règles de croissance, vous êtes peut être arrivés a faire ralentir votre machine. C’est probablement dû a un trop grand nombre d’organes, même si il n’y en a pas forcément beaucoup de visibles à l’écran. Pour remédier a cela, nous allons fixer un nombre maximum d’organe par plante.

Tout se fait au moment d’ajouter un organe dans la plante. C’est a  ce moment que nous allons:

  • compter le nombre d’organes
  • vérifier que le nombre max n’est pas atteint. Si il est atteint, aucun organe n’est créé.

Mais cela implique que chaque organe ait accès au même compteur, global à la plante. Ajoutons un membre ‘root’ a notre script. Ce dernier pointera vers le script du premier GameObject dans la hiérarchie. Avec l’ajout des 2 autres membres, numOrgans et maxNumOrgans, respectivement pour stocker le nombre actuel d’organes dans la plante, et le nombre maximum d’organes dans la plante, la définition de la classe commence ainsi:

[snippet id= »111″]

Au début de la méthode addOrgan(), il faut ajouter un test pour vérifier que le nombre maximum d’organe n’est pas atteint. Le cas échéant, la méthode renverra un pointeur nul.

[snippet id= »114″]

A la destruction, d’un organe, il faut décrémenter le compteur, du nombre d’éléments.  Pour compter correctement le nombre de sous organes.  Ajoutons une méthode detachR(), qui va récursivement détruire tous les éléments d’un organe, en prenant soin de décrémenter le compteur global. Cette fonction sera enrichie par la suite.

[snippet id= »119″]

Actuellement, le seul endroit ou l’on retire un organe, c’est lorsque l’on clique dessus. La méthode OnMouseOver() est changée de la sorte:

[snippet id= »117″]

Re-testez en augmentant la profondeur autorisée à 10, voire 20, vous verrez que la plante ne se développe pas complètement. Mais si vous élaguez la plante d’un coté, elle pourra reprendre sa croissance. Le code complet après l’ajout de cette limitation peut être trouvé dans cette archive.

Une dernière remarque: notre structure de donnée n’est pas optimale, dans le sens ou certains paramètres globaux à la plante n’ont pas besoin d’être déclarés dans chaque organe. Pour les besoins du tutoriel, nous laisserons le code en l’état.

Durée de vie des organes

Pour avoir la joie d’observer les nombreuses variations que l’on peut obtenir, sans avoir à cliquer sur la plante, donnons enfin une durée de vie aux organes, ce qui permettra de les faire disparaître automatiquement après un certain temps, pour les remplacer par d’autres.

Commençons par ajouter quelques variables pour fixer une durée de vie.

[snippet id= »112″]

Le détachement ne va plus détruire les éléments, mais arrêter la croissance en plaçant le flag enableGrowth à false, et en fixant la fin de vie 400 ms après, le temps de faire une rapide animation pour faire disparaître les organes.

[snippet id= »120″]

Enfin, -morceau de choix- la méthode update, ici reproduite en intégralité.

[snippet id= »122″]

Le code final pour cette partie peut être téléchargé ici.

Placement de la caméra

Dernier point abordé dans cette partie, le placement et le contrôle de caméra. Il suffit de créer le script suivant et l’assigner a la caméra de la scène (mais tout autre objet peut convenir). Il place la caméra automatiquement, et les flèches du clavier permettent de tourner autour de la plante.

[snippet id= »109″]

Pour la dernière partie, nous allons améliorer la façon dont les organes sont éliminés de la scène. Avant de les faire disparaître, nous allons utiliser le moteur physique pour les faire chuter, ou les faire partir en éclats… Nous en profiterons aussi pour animer les plantes avec un peu de mouvement, pour simuler du vent.