# Unreal : TP twin stick shooter ## Précisions sur le Framework Unreal - Actor : Tout objet pouvant être placé dans le monde - Pawn : un acteur pouvant être controlé par un joueur ou une IA - Character : un pawn ayant les propriétés d'un personnage. Ex : marcher, courir, sauter - Component : Blocs qui permettent de construire un acteur. Lui donner des comportements et des capacitées - Blueprint : Logique qui définit les fonctionnalités d'un acteur. "scripts visuel" - Controller : "Cerveau", Contrôle un pawn. - AIController - PlayerController - GameMode : "Game manager", gère les règles du jeu. ## Step 1 : Créer la map - File-> New Level -> Empty Level - Lighting - ouvrir le env light mixer: Window -> Env. Light Mixer - ajouter toutes les lights - Selectionner le mode d'affichage Normal ![image](https://hackmd.io/_uploads/S1aAjPQV6.png) - activer l'option realtime capture dans la SkyLight - activer l'option volumetric fog dans l'ExponentialHeightFog **Video** : https://drive.google.com/file/d/1Kz8XctZzSqveC9g0kBNmKT3fesfJpUdD/view?usp=sharing - Ranger les lights dans un dossier dans l'outliner. F2 pour renommer. ![lighting](https://hackmd.io/_uploads/BkjWDr9Vp.gif) - utiliser le mode modeling de l'éditeur. - cube grid **Video** : https://drive.google.com/file/d/14RnDCyQnE0Pirm6sl2a4han9aG7IKOoz/view - attribué 2 materiaux avec l'outil MatEd ![image](https://hackmd.io/_uploads/BJqt5P7VT.png) //**insert video**// https://drive.google.com/file/d/1cZeWE6oLvWrTkBWFS1kotS7hGegb_1mC/view?usp=sharing ## Step 2 : Créer le blueprint du joueur - Créer un blueprint de type Character nommé BP_Ship Click droit dans le Content Drawer (CTRL + Espace pour le faire apparaitre). ![image](https://hackmd.io/_uploads/BkrG5H9Np.png) - Ouvrez le avec un double click. - ajouter un Cone comme placeholder du vaisseau ![addcone](https://hackmd.io/_uploads/SyaZjrqNT.gif) - orienter sa pointe en direction de l'axe X+ - Créer deux enfants de ce blueprint, BP_Player et BP_Enemy. Click droit sur le BP_Ship -> Create Child Blueprint Class. ![image](https://hackmd.io/_uploads/ByhpOSc4a.png) - Ranger ces blueprints dans un nouveau dossier nommé "Core". Vous pouvez changer la couleur du dossier. Click droit sur le dossier -> Set Color ![image](https://hackmd.io/_uploads/BJTotBcVp.png) - Créer un Material nommé M_Ship - Ouvrez le material et créez un parametre Base Color. Click droit sur "Base Color" -> Promote to parameter. ![createparam](https://hackmd.io/_uploads/rkOpsScNa.gif) - N'oubliez pas de sauvegarder le material. - Assignez le au cone du BP_Ship - Nous allons maintenant créer une petite logique pour changer la couleur du vaisseau player et du vaisseau enemy. Grace à l'héritage nous n'aurons besoin de coder cela seulement dans le blueprint parent. BP_Ship. Ouvrez le BP_Ship et ajoutez cette logique dans le construction script du BP_Ship : - ![image](https://hackmd.io/_uploads/SkawWn3NT.png) - ![image](https://hackmd.io/_uploads/B1dDtjQNa.png) - Pour créer la variable Color, faites clique droit sur le parametre value et renommez la. ![image](https://hackmd.io/_uploads/ryxiKi7Ep.png) - Changez la couleur du BP_Player et du BP_Enemy grace à la variable hérité du parent BP_Ship. - pour afficher les variables héritées ![image](https://hackmd.io/_uploads/BkJsH_7ET.png) - Ajoutez une camera au joueur - ajoutez un composent Spring puis un camera en enfant. - pivotez le spring sur l'axe Y de -60 - Eloignez la camera grace à au parametre "Target Arm Length" : 800 ![image](https://hackmd.io/_uploads/HJhu8_mE6.png) - Decochez les paramètres (Do collision test, Inherit Pitch Yaw Roll) ![image](https://hackmd.io/_uploads/Sy2ERo7V6.png) ## Créer et parametrer le game mode - Créez un game mode nommé BP_GameMode_Shooter Click Droit dans le drawer -> Blueprint Class -> GameMode Base - Définir le parametre Default Pawn Class avec BP_Player. ![image](https://hackmd.io/_uploads/S1z6ouQV6.png) - Définir ce game mode par défaut dans les project settings, maps and modes. Edit -> Project Settings -> Maps & modes -> Default GameMode - Ajouter un objet Player Start sur la Map. Celui-ci servira de point de spawn au joueur. ![image](https://hackmd.io/_uploads/r1E_GI9Na.png) ![image](https://hackmd.io/_uploads/SkWafL9Ep.png) ## Step 3 : Setup les inputs avec Enhanced Input System - Créez un nouveau dossier Inputs dans Core - Créer 4 input action - **INP_Fire** & **INP_LookAround** : Pas de changement. - **INP_MoveAround** & **INP_AutoFire** : Changez leur type en Axis2D ![image](https://hackmd.io/_uploads/rJU3QIqEp.png) - Créer un Input Mapping Context nommé IMC_TwinStickShooter - Parametrez INP_Fire - Parametrez INP_MoveAround ![image](https://hackmd.io/_uploads/SyNG88qEp.png) - Relier l'IMC au BP_Player dans l'event graph ![image](https://hackmd.io/_uploads/rka00_7Vp.png) - Tester l'input ![image](https://hackmd.io/_uploads/S1wWJK7N6.png) (La sortie Triggered est appelé tant que l'input est appuyé) (La sortie Started est appelé une fois quand l'input est appuyé) Lancez le jeu avec le bouton Play et clickez dans le viewport pour focus le jeu. Lorsque vous clickez gauche vous devriez vous le message "Fire" en haut à gauche. ![image](https://hackmd.io/_uploads/rJmq8LqEp.png) ### Coder le déplacement au joystick - Toujours dans l'event graph du BP_Player : ![script_01](https://hackmd.io/_uploads/SJ7NuUcNT.gif) ![image](https://hackmd.io/_uploads/SJhYOU9ET.png) ### Coder l'orientation au joystick - Ajoutez l'input AutoFire dans l'input mapping context ![image](https://hackmd.io/_uploads/SJXQKL5Va.png) - Ajoutez ce code dans l'event graph ![image](https://hackmd.io/_uploads/S1hE9I9ET.png) - Testez. Vous devriez pouvoir orienter le vaisseau en bougant le joystick droit. Mais vous devriez également remarquer que l'axe Y est inversé. Vous allez pouvoir corriger cela en ajouter un modifier "Negate" dans l'Input Mapping Context. ![image](https://hackmd.io/_uploads/SJz0cUqV6.png) #### Simuler un jostick avec le clavier - Pour pouvoir jouer également au clavier. Vous allez ajouter des touches dans l'Input Mapping Context. Ce parametrage vous semblera peut-être étrange car nous allons émuler une input 2D avec des simples touches. Mais il permet de ne pas ajouter d'autres inputs actions et donc le code. - ![image](https://hackmd.io/_uploads/HJQya85ET.png) - ![image](https://hackmd.io/_uploads/H1HIpIcVa.png) ## Step 4 : Créer un projectile - Creez un blueprint BP_Projectile (Actor) - ajouter une sphere et l'applatir ![image](https://hackmd.io/_uploads/B18M-v9V6.png) - Collision Presets : No Collision - Ajouter une sphere collider ![image](https://hackmd.io/_uploads/H1AobPqE6.png) - sphere radius : 4 - Rendre ce collider parent du mesh.![image](https://hackmd.io/_uploads/Skt5GPqV6.png) - Creez un material M_Projectile ![image](https://hackmd.io/_uploads/rk-a0U9Na.png) Blend mode : Additive. Shading Model : Unlit. Promote to parameter Emmissive Color. - Assignez ce material au projectile - Ajoutez un component "ProjectileMovement" ![image](https://hackmd.io/_uploads/BJCRyP94a.png) Parametres: - Projectile Gravity Scale : 0 - Initial Speed & Max Speed : 1000 - Drag'n'drop un projectile à coté du éplayer start - Appuyez sur Play, Vous devriez voir le projectile partir tout seul. ### Coder les dégats du projectile - Lorsque le projectile entrera en collision avec un autre objet. L'evenement OnComponentBeginOverlap sera levé. En fonction de l'objet qui aurat été touché nous lui ferons des dégats ou pas. Pour faciliter ce choix. Vous allez ajouter une **"Interface" "Damageable"** aux objets endommageable. #### **Les Interfaces** sont des classes particulières qui s'ajoutent à une autre classe. Elle obligent la classe sur laquelle elle sont ajoutée à implémenter ses fonctions déclaré. Elles ne contiennent pas de code mais seulement des déclaration de fonction. C'est une sorte de promesse de fonctionnalité. - Creez une interface BPI_Damageable ![image](https://hackmd.io/_uploads/BJ4TIwqE6.png) - Déclarez une fonction AffectHealth - Inputs : Deltat de type Float ![image](https://hackmd.io/_uploads/HknQDv5ET.png) - Ajoutez cette interface au BP_Enemy dans les "Class Settings" ![image](https://hackmd.io/_uploads/rkuJOwcN6.png) - Vous devriez ensuite voir apparaitre à gauche la catégorie Interfaces. ![image](https://hackmd.io/_uploads/SypmdPqE6.png) - Double clickez dessus pour commencer à implémenter cette fonction. ![image](https://hackmd.io/_uploads/HkxWKv9N6.png) - Codez la logique dans le BP_Projectile ![image](https://hackmd.io/_uploads/BJE6-ucVT.png) Lorsque le projectile touche un objet. Il vérifie si cet objet implement l'interface BPI_Damageable. Si oui, il appel sa fonction affectHealth(-100). - Placez un BP_Enemy devant le projectile, vous devriez voir le message "Ouille" lorsqu'il est touché. ![image](https://hackmd.io/_uploads/SJ0nqD9NT.png) ## Step 5 : Gérer les points de vie du joueur et des ennemis - Le joueur et les ennemis ont tous des points de vie. Vous pouvez donc confier leur gestion à leur classe parent. - Dans le BP_Ship, créez 2 variables - float HealthPoints = 100 - booleen isDead = false - Ajoutez un custom event pour vérifier si le vaisseau est mort. Nommez le UpdateIsDead. ![image](https://hackmd.io/_uploads/BJThpDq46.png) - Créez une fonction UpdateHealthPoints avec un parametre d'entrée float nommé Delta. ![image](https://hackmd.io/_uploads/SyMk0w5N6.png) ## Step 6 : Continuer la gestion des dégats du projectile dans les ennemis. - Reprenez le code de l'event Affect Healt du BP_Enemy ![image](https://hackmd.io/_uploads/BkmeGOqET.png) - L'ennemi devrait maintenant disparaitre lorsqu'il est touché par le projectile. ## Step 7 : Créer une arme - Créez un BP_Gun. Ce sera un acteur. - Ajoutez un cube, aplatissez le pour qu'il ressemble à ca : ![image](https://hackmd.io/_uploads/r1dmg23E6.png) - Désactivez ses collisions. **Collision Presets : NoCollision** ![image](https://hackmd.io/_uploads/BySRehh46.png) - Ajoutez un component Arrow pour définir le point de spawn des projectiles. Renommez le "ProjectileSpawnPoint", placez le devant le cube : ![image](https://hackmd.io/_uploads/rJJDen3Na.png) - Codez ces 3 evenements : - **FireOneProjectile** : il fera spawn un BP_Projectile sur le ProjectileSpawnPoint. - **StartFiring** : Appelera l'event FireOneProjectile en boucle grace à un **Timer**. - **StopFiring** : Arrêtera le Timer. ![image](https://hackmd.io/_uploads/ByftX32Na.png) ## Step 8 : Lier l'arme au joueur et tirer avec - Ajoutez une reference du BP_Gun dans le **BP_Player** - Ajoutez un nouveau component **"ChildActor"** en enfant du Mesh. ![image](https://hackmd.io/_uploads/SyitEh2Na.png) - Renommez le Gun. - Assignez lui la classe BP_Gun ![image](https://hackmd.io/_uploads/Sk2GS23NT.png) - À la suite du begin play dans le BP_Player, Stockez référence du gun dans une variable ![image](https://hackmd.io/_uploads/Hk4NQ_5Np.png) - Créez 2 fonctions, StartFire et StopFire ![image](https://hackmd.io/_uploads/Ske-E_5E6.png) ![image](https://hackmd.io/_uploads/rJ3WN_5Np.png) - Mettez à jour l'event INP_AutoFire ![image](https://hackmd.io/_uploads/HyqwVOcNp.png) ## Step 9 : Le déplacement des ennemis - ajouter un **Nav mesh bounds volume** dans la map. Faire en sorte qu'il couvre toute la map. - appuyer sur P dans le viewport pour le visualiser ![image](https://hackmd.io/_uploads/SJKUPT2N6.png) - ### Pour gérer les mouvements des ennemis vous allez créer un AI_Controler - Click droit dans le content drawer -> Blueprint Classe -> AI controler . Nommez le AIC_Enemy - ![image](https://hackmd.io/_uploads/rks4dphVT.png) - Codez une logique pour que ce controlleur pourchasse le joueur.![image](https://hackmd.io/_uploads/BJgE1tT34p.png) - Get Controlled Pawn retourne le BP_Enemy sur lequel le controlleur est. - Get Player Pawn retourne le joueur - AI Move To est une fonction predéfini de la classe AI_Controler, elle déplace l'IA vers un point ou un autre acteur. - Appelez l'evenement ChasePlayer une fois au démarrage ![image](https://hackmd.io/_uploads/By0-3T246.png) - Assignez ce controlleur au BP_Enemy ![image](https://hackmd.io/_uploads/ryJMiTnEp.png) - Testez en mettant un BP_Enemy sur la map. Celui ci devrait venir vers votre joueur. Mais une fois qu'il a atteint votre position, il arrête de vous suivre. C'est normal car il a fini d'executer l'orde "Move To" que vous lui avez donné au démarrage. Pour qu'il continue à vous suivre vous allez lui donner cet ordre en boucle. Avec un Timer. ![image](https://hackmd.io/_uploads/SyJETp24a.png) - Ici, nous utilisons une nouvelle methode pour créer un timer. Set Timer **by Event** . Cette méthode demande de relier l'evenement qui doit être appelé par un cable rouge. Cette méthode est plus pratique que le "Set Timer by Function Name" car vous pouvez changer le nom de l'event sans casser votre code. ## Step 10 : Gérer le spawn des ennemis. - Créer un nouvel actor, BP_EnemySpawner. - Ajoutez un box collision et parametrez la. - Collision Presets : No Collision - Shape -> line thickness : 2 - Shape -> Color : Vert - ![image](https://hackmd.io/_uploads/ByUMk03Na.png) - Mettez ce blueprint sur la map au dessus du sol puis élargissez le. Les ennemies tomberons de cette zone, assurez vous donc qu'elle soit au dessus du "NavMesh".![image](https://hackmd.io/_uploads/BJR_eR2ET.png) - Codez la logique de spawn ![image](https://hackmd.io/_uploads/SkzZz024a.png) - Ici on utilise Spawn AIFrom Class plutôt que Spawn Actor car le BP_Enemy possède un AI_Controler - On utilise la box créé plus tôt pour piocher aléatoirement un point de spawn. - On appel l'event SpawnOneEnmy en boucle grace à un timer. ## Step 11 : Gérer les attaques des ennemis. - Dans le BP_Enemy, Ajoutez une box collision nommé HitBox ![image](https://hackmd.io/_uploads/HJqyoa6r6.png) - Ici on test la présence d'un tag "Player" sur l'actor, en plus de tester l'implémentation de l'interface BPI_Damageable, car les BP_Enemy ont eux aussi cette interface. Alors **n'oubliez pas d'ajouter un tag "Player" dans les paramètres du BP_Player.** - Dans le BP_Enemy, Codez l'event begin overlap (hitbox): - Stockez dans une nouvelle variable nommé "Actor Target" le player attaqué. ![image](https://hackmd.io/_uploads/Hybu91SS6.png) - Créez une fonction "Attack" ![image](https://hackmd.io/_uploads/S1s7ikrSa.png) - Damges = -10 - Completez l'event begin overlap pour attaquer en boucle ![image](https://hackmd.io/_uploads/rk-Fs1BBT.png) ici on utilise une nouvelle méthode pour créer un timer. Tirez le cable rouge Event et ajoutez le node "Create Event". Puis choisissez la fonction ou l'event qui sera appelé (ici : Attack()). - Codez l'event End Overlap (hitbox) pour arrêter de faire des dégats quand on ne touche plus le joueur. ![image](https://hackmd.io/_uploads/By4RXTaSp.png) ## Step 12 : Gérer la mort du joueur et le respawn avec le Game Mode. - Dans le BP_Player, ajoutez l'interface BPI_Damageable pour qu'il puisse implémenter la fonction AffectHealth. ![image](https://hackmd.io/_uploads/SJaq5TTHT.png) - /!\ Si votre joueur meurt lorsque vous tirez, c'est surement parceque son projectile spawn dans son collider. bougez le gun en dehors du collider pour évitez ca. Nous coderons plus tard une logique pour ca. - Dans le BP_GameMode_Shooter, codez un custom event "RespawnPlayer". ![image](https://hackmd.io/_uploads/H1IBJCpH6.png) Rendez la variable PlayerSpawnTransform public en cliquant sur l'oeil à côté ![image](https://hackmd.io/_uploads/B1Qs106S6.png) -> ![image](https://hackmd.io/_uploads/BJW31RTB6.png) - Dans le BP_Player, au démarrage du jeu (begin play), vous allez envoyer la position du Player au game mode via cette variable. ![image](https://hackmd.io/_uploads/BJlcWATra.png) - On en profite pour stocker la référence du game mode pour plus tard. - Appelez l'event RespawnPlayer du game mode quand le joueur meurt. ![image](https://hackmd.io/_uploads/ryxYfRprp.png) ## Step 13 : Gérer le score. - Dans le game mode, créez une variable CurrentScore de type Integer. - Creez une nouvelle interface pour le game mode "BPI_GameMode_Functions". Cela nous servira à appeler ses fonctions plus simplement (sans "Cast" donc plus optimisé). - Ajoutez un fonction nommé UpdateScore dans l'interface. Et liez la au game mode. - Dans le game mode, implementez la fonction UpdateScore de l'interface ![image](https://hackmd.io/_uploads/Bk8VUy0HT.png) - Dans le BP_Enemy, appelez la fonction Update score du game mode lorsque l'ennemi meurt. ![image](https://hackmd.io/_uploads/HyInIkCHa.png) ## Step 14 : Limiter le nombre d'ennemis sur la map. - Vous allez devoir ajouter ces fonctions à l'interface BPI_GameMode_functions ![image](https://hackmd.io/_uploads/ByFmSM0Sp.png) - RegisterSpawner Input : NewSpawner de type BP_EnemySpawner - CanSpawnOneEnemy Output : Result de type Boolean - Implementez toutes ces nouvelles fonctions dans le game mode - ![image](https://hackmd.io/_uploads/SyPgIGAH6.png) - ![image](https://hackmd.io/_uploads/rJV-UfCSp.png) - le node "++" ajoute 1 à la variable - le node "--" retire 1 à la variable - ![image](https://hackmd.io/_uploads/BJxG8fRBa.png) - Modifiez le BP_EnemySpawner pour : - L'enregistrer dans le game mode au démarrage - Vérifier s'il peut spawn un ennemi - Incrementer le compteur d'ennemis lorsqu'un nouveau spawn. - ![image](https://hackmd.io/_uploads/HJ2MPzRHa.png) - Modifiez le BP_Enemy pour qu'il decremente le compteur lorsqu'il meurt. - ![image](https://hackmd.io/_uploads/H1k0wMABT.png) ## Step 15 : HUD, Afficher le score. - Creez un Widget Blueprint nommé WBP_HUD ![image](https://hackmd.io/_uploads/S1dH_GRSa.png) - En l'ouvrant vous allez découvrir l'interface de création des UI. **UMG** ![image](https://hackmd.io/_uploads/H1TQAjlUT.png) - Ajoutez des éléments de la "Palette" vers le viewport pour reproduire cet exemple. ![image](https://hackmd.io/_uploads/Hko4JnlIT.png) - Respecter la hierarchie des objets et leurs noms. - L'horizontal box place automatiquement les objets qu'elle contient en fonction de l'ordre hierarchique. - Ancrez l'horizontal box en haut à droite du canvas en modifiant sont paramètre "Anchors". ![image](https://hackmd.io/_uploads/SJgOxne8a.png) - Dans le game mode, codez ceci, pour créer et afficher le widget à l'écran. ![image](https://hackmd.io/_uploads/BJ0y7Q0BT.png) - On en profite pour stocker la référence du widget pour plus tard. - Pour mettre à jour le score vous allez créer une fonction dans le WBP_HUD. Pour cela, passez du mode "Designer" à "Graph". Ensuite cela marche comme les autres blueprints. ![image](https://hackmd.io/_uploads/HJF_ssgU6.png) - Créez une fonction nommée "UpdateScoreHUD", avec un input "int" "New Score" ![image](https://hackmd.io/_uploads/B1Xv2igUp.png) - La variable "Score Number" provient du mode Designer du widget, elle correspond au composent Text ajouté pour afficher le score. Pour le transformer en variable, cochez la case "Is Variable" dans ses paramètres. ![image](https://hackmd.io/_uploads/Hkj3nslUT.png) - Vous pouvez maintenant utiliser cette fonction dans le game mode. ![image](https://hackmd.io/_uploads/HkevMhlUT.png) ## Step 16 : HUD, ajouter la barre de vie. - Ajoutez un progress bar au widget. placez la en haut à gauche. ![image](https://hackmd.io/_uploads/r1FVrheLa.png) - N'oubliez pas de cocher la case "Is variable" pour y avoir accès dans le graph. - Dans le mode graph du WBP_HUD, créez une nouvelle fonction "UpdateHealthBar", avec un input float "NewHealth". ![image](https://hackmd.io/_uploads/Hk69ShgUp.png) - Ajoutez une nouvelle fonction dans l'interface BPI_GameMode_Functions nommée "UpdateUI_PlayerHealth", avec un input float "NewHealth". - Implementez cette fonction dans le game mode. ![image](https://hackmd.io/_uploads/SkD58ne8a.png) - Vous êtes presque prêt à utiliser cette fonction dans le BP_Player pour mettre à jour la health bar, mais avant vous allez devoir normaliser la vie du joueur. Car la valeur de la progress bar va de 0 à 1. Normaliser ce genre de valeurs est une bonne pratique, car beaucoup de systemes fonctionnent avec des float entre 0 et 1. Notamment pour les VFX et SFX. Nous allons donc créer une fonction "GetNormalizedHealth" dans le BP_Ship, car cela poura nous servir aussi pour les ennemis. - Voici la fonction GetNormalizedHealth à ajouter dans BP_Ship. ![image](https://hackmd.io/_uploads/SJPKA4DUT.png) - Pour normaliser les points de vie, il nous faut les diviser par leur montant maximum. Donc vous devez créer la variable "MaxHealhPoints" (= 100). Donc si Health = 100 et MaxHealt = 100 , HealthNormalized = 1 . (100/100=1). - Cochez l'option "Pure" dans les parametres de la fonction. Cela lui permet de se passer du pin d'execution (fil blanc). Fonction pure : ![image](https://hackmd.io/_uploads/H10clrDI6.png) Fonction normale : ![image](https://hackmd.io/_uploads/HylhxSDI6.png) - Utilisez la fonction UpdateUI_HealthBar du game mode dans le BP_Player ![image](https://hackmd.io/_uploads/BJnGZSDI6.png) - ici on utilise la fonction pure "GetNormalizedHealth". ## Step 17 : Ajouter du son. - Créez un dossier Audio - Importez un son de tir (.wav) - Créez un sound cue nommé **A_FireProjectile_Cue** dans votre dossier, c'est une sorte de blueprint pour l'audio, dans lequel vous allez pouvoir définir des logiques comme par exemple, moduler le pitch de son, choisir le son à jouer aléatoirement dans une liste ou choisir le son à jouer en fonction d'un parametre. ![image](https://hackmd.io/_uploads/SJFv8enOp.png) - Ouvrez ce sound cue et glissez le son de tir que vous avez importer dans le graph, puis reliez le au node Output. ![image](https://hackmd.io/_uploads/Skw_Oenda.png) - Maintenant il faut déclancher ce sound cue lorsqu'on tir un projectile, donc dans le BP_Gun dans l'event FireOnProjectile. Avec le node **SpawnSound2D** ![image](https://hackmd.io/_uploads/rySgcx3up.png) - Pour améliorer le rendu audio, ajoutez un node **modulator** dans le sound cue, pour faire varier le pitch du son. Cela le rendra moins répétitif. ![image](https://hackmd.io/_uploads/ByAsox3_T.png) - Ajoutez une musique de fond. - importez un fichier audio - créez un sound cue - cochez le parametre "Looping" - Glissez le sound cue au centre de votre map. - Ajoutez un son d'explosion lors de la destruction des ennemis.