
Pendant 9 mois, nous avons travaillé avec DOWiNO et l’Université Paris Descartes sur un serious game médical. Effic’asthme est disponible à la fois sur le Play Store ( https://play.google.com/store/apps/details?id=fr.parisdescartes.efficasthme ) et sur l’App Store ( https://itunes.apple.com/fr/app/efficasthme/id1400814236?mt=8 ).
L’application cible les parents d’enfants souffrant d’asthme pour les aider à faire face aux crises d’asthme. Elle s’appuie sur et est soutenue par la thèse d’un doctorant en santé, David DRUMMOND. (Lien vers la thèse - en français )
Effic’asthme propose : un plan d’action numérique pour faire face aux crises d’asthme, une petite encyclopédie sur les crises d’asthme, un journal, ainsi qu’un simulateur avec des comportements médicaux réalistes et un écran de debriefing de l’événement.
Dans la suite de cet article, je vais expliquer les parties les plus importantes d’Effic’asthme : le simulateur.
La partie simulateur

Le simulateur combine 3 éléments : un état médical de l’enfant, une logique médicale et un gestionnaire de scénario.
État de l’enfant
L’état de l’enfant est bien évidemment l’état de l’enfant dans le simulateur. Il contient le statut médical de l’enfant (température, toux, respiration anormale, …).
Au début de la simulation, il est configuré par le gestionnaire de scénario. Ensuite, il sera affecté par la logique médicale, et dans certains cas particuliers par le gestionnaire de scénario.
L’état de l’enfant contrôle les modèles de personnages 3D (animation et shader) pour afficher les informations de santé.
Gestionnaire de scénario
Le gestionnaire de scénario est la partie scénario du simulateur. Il initialise la simulation, donne un contexte, et peut modifier la simulation en fonction du scénario.
Un scénario est un ScriptableObject pour la persistance. La structure de données d’un scénario est représentée ci-dessous.

Ce gestionnaire enregistre également toutes les actions et événements du simulateur. C’est grâce à ce log que le gestionnaire peut savoir où nous en sommes dans le scénario (étapes du scénario), et déclencher des modifications sur la simulation (action de scénario).
Le gestionnaire et son log sont la pierre angulaire entre la simulation et le debriefing.
Logique médicale
Cette partie est relativement simple. Une action est réalisée, une conséquence est appliquée, et l’événement (l’action et sa conséquence) est enregistré dans le log du gestionnaire de scénario.
La logique médicale utilise l’état de l’enfant et des informations médicales sur l’enfant (poids, planning médical, …) pour déterminer la conséquence d’une action. Elle peut être Bonne, Sans effet, ou Mauvaise. Les conséquences sont appliquées sur l’état de l’enfant.
Certaines actions, comme le spray médical, nécessitent plus d’interaction qu’un simple clic sur un bouton. C’est également la logique médicale (en particulier un sous-module pour chaque médicament) qui gère le système de manipulation et envoie les événements de manipulation. En suivant le protocole médical et l’interaction de l’utilisateur (mouvement des doigts, trigger 3D), le système peut signaler les bonnes et mauvaises manipulations.
Vous pouvez voir ci-dessous un schéma de l’intégration du simulateur.

Lorsque l’utilisateur souhaite arrêter, ou que le scénario arrête la simulation (Time out), le simulateur se ferme et le debriefing commence.
La partie debriefing
Le debriefing est composé de 2 aspects : le journal (diary log) et la correction dynamique.
Journal de debriefing

Le journal récupère le gestionnaire de scénario pour lire l’état initial de la simulation, le scénario et le log.
Il va comparer le scénario et le log pour déterminer si vous avez correctement géré la situation (fait tout le scénario et n’avez pas commis de grosse erreur). Il va ensuite lire chaque entrée du log, examiner les conséquences, pour déterminer le résultat de l’action : Bon, Partiellement bon (bonnes conséquences, mauvaise manipulation), ou si l’état de santé était Pire après coup. Il va également consulter le scénario pour vérifier si l’action a été Mal chronométrée. Des informations supplémentaires seront fournies en fonction du résultat de l’action.
Dans la plupart des scénarios, certaines actions comme Donner le médicament d’urgence sont obligatoires. Une fois la lecture du log de simulation terminée, on vérifie si ces actions obligatoires ont été réalisées. Si ce n’est pas le cas, de nouvelles entrées d’affichage sont ajoutées pour avertir l’utilisateur de ses erreurs.
Pour conclure, le debriefing attribuera un score à cette session. Pour chaque entrée affichée précédemment, le système calculera les points associés, en fonction du résultat de l’action et d’un tableau fourni par les game designers. De plus, certaines actions non réalisées rapporteront ou coûteront des points selon le scénario.
Une note sera attribuée en fonction de votre progression dans le scénario en cours. Si vous obtenez une mauvaise note (< 50%), le debriefing vous proposera de jouer la correction dynamique du scénario.
Correction dynamique

Le correcteur dynamique est une version guidée d’un scénario. C’est un module en couche supplémentaire sur le simulateur.
Un premier écran affiche l’état médical actuel de l’enfant. Chaque symptôme d’asthme est vérifié et un rapport médical est établi avec la gravité de la crise. Si l’état de l’enfant change pendant la simulation, cet écran sera à nouveau affiché.
La simulation se lance ensuite et la correction dynamique contrôle l’UI et certaines interactions pour guider l’utilisateur.
En fonction des actions nécessaires, la correction dynamique compose un scénario parallèle avec des blocs de patterns scriptés.
Chaque bloc de pattern scripté est conçu manuellement. Il possède une file (liste séquentielle) d’événements de simulation et de réactions (modifier l’UI, limiter l’interaction utilisateur, envoyer une requête au simulateur). Les séquences d’événements de simulation sont conçues pour suivre les événements envoyés par le simulateur.
Le correcteur dynamique suit son scénario (file de blocs de patterns scriptés). Pour chaque événement envoyé par le simulateur correspondant au pattern scripté en cours, la réaction associée est appliquée. Lorsque tous les événements du pattern scripté ont été déclenchés, le pattern scripté suivant est sélectionné. Lorsque tous les patterns scriptés du scénario ont été consommés, la correction dynamique se termine.
Un schéma descriptif de la correction dynamique est disponible ci-dessous.

Particularités et défis :
Localisation
Effic’asthme sera utilisé, au minimum, en deux langues : français et anglais. Pour faciliter la localisation, nous utilisons un plugin appelé I2Loc. Nous avons pu localiser les textes, les sons, les images et aussi les vidéos.
La fonctionnalité utile d’I2Loc est le fournisseur google sheet. Au lieu d’avoir un fichier .csv ou .xml, le plugin utilise une feuille google sheet stockée dans un google drive. La traduction peut ainsi être réalisée pendant ou après le développement, sans aucune modification du build. La période de rafraîchissement peut être modifiée selon les besoins.
Un terme de localisation (texte, image, son, …) est identifié par un id de type chaîne de caractères. Pour rendre cela plus utilisable, nous avons implémenté des enums et des static readonly dictionaries. Ainsi, nous pouvons centraliser les ids et éviter les erreurs de nommage.
Animations 3D
C’est une partie importante du projet en raison du réalisme requis. À cause du processus artistique, nous avons décidé d’utiliser des animations en point cache.
Les animations en cache sont des animations similaires aux blend shapes, mais elles sont séparées du modèle 3D. Le logiciel d’animation capture les sommets sur une zone du modèle et échantillonne leurs positions périodiquement. Ces échantillons sont ensuite écrits dans un fichier, un .mdd dans ce cas. Ainsi, les artistes peuvent créer les animations et les livrer progressivement, sans avoir besoin des précédentes ni du modèle. En revanche, selon le nombre de sommets et la fréquence d’échantillonnage, les fichiers d’animation peuvent être extrêmement lourds. Cela peut poser problème pour une application mobile.
Unity ne peut pas lire ce type d’animation, nous utilisons donc un plugin qui les lit, MegaFiers. MegaFiers modifie la géométrie du mesh selon les instructions du .mdd et une certaine extrapolation. Les animations sont jouées dans plusieurs scripts attachés au GameObject possédant le mesh. Pour un usage plus pratique, je préfère relier ces scripts au animation controller via des animation clips. Cela fonctionne très bien, sauf pour le blending d’animations.
Nos animations couvrent tout le corps de l’enfant et certains artefacts apparaissent lorsque le blending est appliqué. Certains sommets s’écartent selon leur position dans les animations. Par itérations, j’ai découvert que le blending en début d’animation était la partie la plus stable.
Ce type d’animation offre plus de flexibilité aux artistes, alors qu’elle est plus difficile à intégrer pour les programmeurs et peut être extrêmement lourde.
Retrouvez plus d’informations sur notre site : https://davikingcode.com/fr/projets/efficasthme