Il s'agit de la deuxième partie du didacticiel 
«Création d'un jeu Tower Defense dans Unity» . Nous créons un jeu de genre de tower defense dans Unity, et à la fin de la 
première partie , nous avons appris comment placer et améliorer des monstres. Nous avons également un ennemi qui attaque les cookies.
Cependant, l'ennemi ne sait pas encore où chercher! De plus, une attaque à elle seule semble étrange. Dans cette partie du tutoriel, nous ajouterons des vagues d'ennemis et des monstres armés afin qu'ils puissent défendre un précieux cookie.
Se rendre au travail
Ouvrez le projet dans Unity, que nous avons arrêté dans la dernière partie. Si vous venez de nous rejoindre, téléchargez le 
projet de projet et ouvrez 
TowerDefense-Part2-Starter .
Ouvrez 
GameScene à partir du dossier 
Scenes .
Transformez vos ennemis
À la fin du didacticiel précédent, l'ennemi a appris à se déplacer le long de la route, mais il semble qu'il ne sache pas où chercher.
Ouvrez le script 
MoveEnemy.cs dans l'EDI et ajoutez-y la méthode suivante pour corriger la situation.
private void RotateIntoMoveDirection() {  
RotateIntoMoveDirection fait tourner l'ennemi afin qu'il 
RotateIntoMoveDirection toujours vers l'avant. Il le fait comme suit:
- Calcule la direction actuelle du bug, en soustrayant la position du waypoint actuel de la position du point suivant.
- Utilise Mathf.Atan2pour déterminer l'angle en radians vers lequelnewDirectiondirigé (le point zéro est à droite). Multiplie le résultat par180 / Mathf.PI, convertissant l'angle en degrés.
- Enfin, il obtient l'enfant Sprite et fait pivoter les degrés d'axe rotationAngle. Notez que nous faisons pivoter l' enfant , pas le parent, de sorte que la bande d'énergie que nous ajoutons plus tard reste horizontale.
Dans 
Update() , remplacez le commentaire 
// TODO: prochain appel à 
RotateIntoMoveDirection :
 RotateIntoMoveDirection(); 
Enregistrez le fichier et revenez à Unity. Exécutez la scène; maintenant l'ennemi sait où il va.
Maintenant, le bug sait où il va.
Le seul et unique ennemi n'a pas l'air très impressionnant. Nous avons besoin de hordes! Et comme dans tout jeu de tower defense, les hordes courent par vagues!
Informer le joueur
Avant de commencer à déplacer les hordes, nous devons avertir le joueur de la bataille imminente. De plus, il vaut la peine d'afficher le numéro d'onde actuel en haut de l'écran.
Les informations sur les 
vagues sont requises par plusieurs GameObjects, nous allons donc les ajouter au composant 
GameManagerBehavior du 
GameManager .
Ouvrez 
GameManagerBehavior.cs dans l'EDI et ajoutez les deux variables suivantes:
 public Text waveLabel; public GameObject[] nextWaveLabels; 
waveLabel stocke un lien vers l'étiquette de sortie du numéro d'onde dans le coin supérieur droit de l'écran. 
nextWaveLabels stocke deux GameObjects qui créent une combinaison d'animation que nous montrerons au début d'une nouvelle vague:
Enregistrez le fichier et revenez à Unity. Sélectionnez 
GameManager dans la 
hiérarchie . Cliquez sur le cercle à droite de l' 
étiquette Wave et dans la boîte de dialogue 
Select Text , sélectionnez 
WaveLabel dans l'onglet 
Scene .
Maintenant, définissez la 
taille des 
étiquettes de vague suivante sur 
2 . Maintenant, définissez l' 
élément 0 sur 
NextWaveBottomLabel , et pour l' 
élément 1 NextWaveTopLabel est le même que nous l'avons fait avec Wave Label.
Voici à quoi devrait ressembler le comportement de Game ManagerSi le joueur perd, il ne devrait pas voir de message sur la prochaine vague. Pour gérer cette situation, revenez à 
GameManagerBehavior.cs et ajoutez une autre variable:
 public bool gameOver = false; 
Dans 
gameOver nous enregistrerons la valeur de la perte ou non du joueur.
Ici, nous utilisons à nouveau la propriété pour synchroniser les éléments du jeu avec la vague actuelle. Ajoutez le code suivant à 
GameManagerBehavior :
 private int wave; public int Wave { get { return wave; } set { wave = value; if (!gameOver) { for (int i = 0; i < nextWaveLabels.Length; i++) { nextWaveLabels[i].GetComponent<Animator>().SetTrigger("nextWave"); } } waveLabel.text = "WAVE: " + (wave + 1); } } 
La création d'une variable, d'une propriété et d'un getter privés devrait déjà vous être familière. Mais avec le setter, encore une fois, tout est un peu plus intéressant.
Nous attribuons à 
wave nouvelle 
value .
Ensuite, nous vérifions si le jeu est terminé. Sinon, parcourez toutes les étiquettes 
nextWaveLabels - ces étiquettes ont un composant 
Animator . Pour activer l'animation 
Animator , nous 
définissons un déclencheur 
nextWave .
Enfin, nous définissons le 
text de 
waveLabel sur 
wave + 1 . Pourquoi 
+1 ? Les gens ordinaires ne commencent pas à compter à partir de zéro (oui, c'est étrange).
Dans 
Start() définissons la valeur de cette propriété:
 Wave = 0; 
Nous commençons le compte avec le nombre 
0 Wave .
Enregistrez le fichier et exécutez la scène dans Unity. L'étiquette Wave affichera correctement 1.
Pour un joueur, tout commence par la vague 1.Vagues: créez des tas d'ennemis
Cela peut sembler évident, mais pour attaquer avec une horde, il est nécessaire de créer plus d'ennemis - alors que nous ne savons pas comment faire. De plus, nous ne devons pas créer la prochaine vague tant que la vague actuelle n'est pas détruite.
Autrement dit, le jeu devrait être capable de reconnaître la présence d'ennemis dans la scène, et les 
balises sont un bon moyen d'identifier les objets du jeu ici.
Marquage des ennemis
Sélectionnez le préfabriqué 
ennemi dans l'arborescence du projet. En haut de l' 
inspecteur, cliquez sur la liste déroulante 
Tag et sélectionnez 
Ajouter un tag .
Créez une 
balise appelée 
Enemy .
Sélectionnez l' 
ennemi préfabriqué. Dans l' 
inspecteur, définissez-lui 
la balise Enemy .
Définir des vagues d'ennemis
Maintenant, nous devons définir la vague d'ennemis. Ouvrez 
SpawnEnemy.cs dans l'IDE et ajoutez l'implémentation de classe suivante avant 
SpawnEnemy :
 [System.Serializable] public class Wave { public GameObject enemyPrefab; public float spawnInterval = 2; public int maxEnemies = 20; } 
La vague contient le 
enemyPrefab - la base pour créer des instances de tous les ennemis dans cette vague, 
spawnInterval - le temps entre les ennemis dans la vague en secondes et 
maxEnemies - le nombre d'ennemis créés dans cette vague.
La classe est 
sérialisable , c'est-à-dire que nous pouvons modifier ses valeurs dans l'inspecteur.
Ajoutez les variables suivantes à la classe 
SpawnEnemy :
 public Wave[] waves; public int timeBetweenWaves = 5; private GameManagerBehavior gameManager; private float lastSpawnTime; private int enemiesSpawned = 0; 
Ici, nous définissons les variables pour le frai des ennemis, ce qui est très similaire à la façon dont nous avons déplacé les ennemis entre les points sur la route.
Nous définissons les vagues d'ennemis individuels par 
waves et suivons le nombre d'ennemis créés et l'heure à laquelle ils ont été créés dans 
enemiesSpawned et 
lastSpawnTime .
Après toutes ces attaques, les joueurs ont besoin de temps pour respirer, alors réglez 
timeBetweenWaves sur 5 secondes.
Remplacez le contenu de 
Start() code suivant.
 lastSpawnTime = Time.time; gameManager = GameObject.Find("GameManager").GetComponent<GameManagerBehavior>(); 
Ici, nous 
lastSpawnTime valeur de l'heure actuelle, c'est-à-dire l'heure à laquelle le script a démarré après le chargement de la scène. Ensuite, nous obtenons le 
GameManagerBehavior déjà familier.
Ajoutez le code suivant à 
Update() :
 
Analysons-le étape par étape:
- Nous obtenons l'indice de la vague courante et vérifions si c'est la dernière.
- Si c'est le cas, nous calculons le temps écoulé après l'apparition précédente de l'ennemi et vérifions s'il est temps de créer un ennemi. Nous prenons ici en compte deux cas. S'il s'agit du premier ennemi de la vague, nous vérifions si timeIntervalesttimeIntervalàtimeBetweenWaves. Sinon, nous vérifions sitimeIntervalesttimeIntervalaux vagues despawnInterval. En tout cas, on vérifie que nous n'avons pas créé tous les ennemis dans cette vague.
- Si nécessaire, enemyPrefabl'ennemi, créant ainsi une instance d'enemyPrefab. Augmentez également la valeur desenemiesSpawned.
- Vérifiez le nombre d'ennemis à l'écran. S'ils ne sont pas là et que c'était le dernier ennemi de la vague, alors nous créons la vague suivante. Toujours à la fin de la vague, nous donnons au joueur 10 pour cent de tout l'or restant.
- Après avoir vaincu la dernière vague, une animation de victoire dans le jeu est jouée ici.
Définition des intervalles d'apparition
Enregistrez le fichier et revenez à Unity. Sélectionnez l'objet 
Route dans la 
hiérarchie . Dans l' 
inspecteur, définissez la 
taille de l'objet 
Waves sur 
4 .
Pour l'instant, sélectionnez un objet 
ennemi pour les quatre éléments comme 
préfabriqué ennemi . Configurez les champs 
Spawn Interval et 
Max Enemies comme suit:
- Élément 0 : Intervalle d'apparition: 2,5 , nombre maximum d'ennemis: 5
- Élément 1 : Intervalle d'apparition: 2 , nombre maximum d'ennemis: 10
- Élément 2 : Intervalle d'apparition: 2 , nombre maximum d'ennemis: 15
- Élément 3 : Intervalle d'apparition: 1 , nombre maximum d'ennemis: 5
Le schéma fini devrait ressembler à ceci:
Bien sûr, vous pouvez expérimenter ces valeurs pour augmenter ou diminuer la complexité.
Lancez le jeu. Ouais! Les coléoptères ont commencé le voyage vers votre cookie!
Tâche supplémentaire: ajouter différents types d'ennemis
Aucun jeu de tower defense ne peut être considéré comme complet avec un seul type d'ennemi. Heureusement, il y a aussi 
Enemy2 dans le dossier 
Prefabs .
Dans l' 
inspecteur, sélectionnez 
Prefabs \ Enemy2 et ajoutez-y le script 
MoveEnemy . Réglez la 
vitesse sur 
3 et définissez 
la balise ennemie . Vous pouvez maintenant utiliser cet ennemi rapide pour que le joueur ne se détende pas!
Mise à jour de la vie du joueur
Même si des hordes d'ennemis attaquent le cookie, le joueur ne subit aucun dégât. Mais nous allons bientôt le réparer. Le joueur doit souffrir s'il permet à l'ennemi de se faufiler.
Ouvrez 
GameManagerBehavior.cs dans l'EDI et ajoutez les deux variables suivantes:
 public Text healthLabel; public GameObject[] healthIndicator; 
Nous utilisons 
healthLabel pour accéder à la valeur vitale du joueur et 
healthIndicator pour accéder aux cinq petits monstres verts à mâcher des biscuits - ils symbolisent simplement la santé du joueur; c'est plus drôle qu'un indicateur de santé standard.
Gestion de la santé
Ajoutez maintenant une propriété qui stocke la santé du joueur dans 
GameManagerBehavior :
 private int health; public int Health { get { return health; } set {  
C’est ainsi que nous gérons la santé du joueur. Et encore une fois, la partie principale du code est située dans le setter:
- Si nous réduisons la santé du joueur, nous utilisons le composant CameraShakepour créer un bel effet de tremblement. Ce script est inclus dans le projet téléchargeable et nous ne le considérerons pas ici.
- Nous mettons à jour la variable privée et l'étiquette de santé dans le coin supérieur gauche de l'écran.
- Si la santé est tombée à 0 et que la fin du jeu n'est pas encore arrivée, gameOversurtrueet démarrez l'animationgameOver.
- Nous supprimons l'un des monstres des cookies. Si nous les désactivons, cette partie peut être écrite plus facilement, mais ici, nous soutenons la réinsertion au cas où la santé serait ajoutée.
Nous initialisons 
Health in 
Start() :
 Health = 5; 
Nous avons réglé la 
Health à 
5 lorsque la scène commence à jouer.
Après avoir fait tout cela, nous pouvons maintenant mettre à jour la santé du joueur lorsque le bug arrive dans le cookie. Enregistrez le fichier et accédez à l'EDI dans le script 
MoveEnemy.cs .
Changement de santé
Pour changer votre santé, recherchez le commentaire dans 
Update() avec les mots 
// TODO: et remplacez-le par ce code:
 GameManagerBehavior gameManager = GameObject.Find("GameManager").GetComponent<GameManagerBehavior>(); gameManager.Health -= 1; 
Nous obtenons donc le 
GameManagerBehavior et soustrayons l'unité de sa 
Health .
Enregistrez le fichier et revenez à Unity.
Sélectionnez un 
GameManager dans la 
hiérarchie et sélectionnez 
HealthLabel pour son 
Health Label .
Développez l'objet 
Cookie dans la 
hiérarchie et faites glisser ses cinq enfants 
HealthIndicators dans le 
tableau des indicateurs de santé de GameManager - les indicateurs de santé seront de petits monstres verts mangeant des cookies.
Exécutez la scène et attendez que les bogues atteignent le cookie. Ne faites rien jusqu'à ce que vous perdiez.
Monster Revenge
Des monstres en place? Oui Les ennemis attaquent-ils? Oui, et ils ont l'air menaçant! Il est temps de répondre à ces animaux!
Pour ce faire, nous avons besoin des éléments suivants:
- Ligne de santé pour que le joueur sache quels ennemis sont forts et lesquels sont faibles
- Détecter les ennemis à portée d'un monstre
- Prendre une décision - sur quel ennemi tirer
- Un tas de coquillages
Barre de santé ennemie
Pour implémenter la bande de santé, nous utilisons deux images - une pour le fond sombre, et la seconde (la barre verte est légèrement plus petite) que nous mettrons à l'échelle en fonction de la santé de l'ennemi.
Faites glisser depuis l' 
arborescence du 
projet vers la scène 
Prefabs \ Enemy .
Ensuite, dans la 
hiérarchie, faites glisser et déposez 
Images \ Objects \ HealthBarBackground sur 
Enemy pour l'ajouter en tant qu'enfant.
Dans l' 
inspecteur, définissez la 
position du HealthBarBackground sur 
(0, 1, -4) .
Ensuite, dans l' 
arborescence du 
projet, sélectionnez 
Images \ Objects \ HealthBar et assurez-vous que son 
pivot est à 
gauche . Ajoutez-le ensuite en tant qu'enfant de l' 
ennemi dans la 
hiérarchie et définissez sa valeur de 
position (-0,63, 1, -5) . Pour l' 
échelle X , définissez la valeur sur 
125 .
Ajoutez un nouveau script 
C # appelé 
HealthBar à l' objet de jeu 
HealthBar . Plus tard, nous allons le changer pour qu'il change la longueur de la barre de santé.
Après avoir sélectionné un objet 
ennemi dans la 
hiérarchie , assurez-vous que sa position est 
(20, 0, 0) .
Cliquez sur 
Appliquer en haut de l' 
inspecteur pour enregistrer toutes les modifications dans le préfabriqué. Enfin, supprimez l'objet 
ennemi dans la 
hiérarchie .
Répétez maintenant toutes ces étapes pour ajouter une barre de santé pour 
Prefabs \ Enemy2 .
Modifier la longueur de la barre de vie
Ouvrez l'IDE 
HealthBar.cs et ajoutez les variables suivantes:
 public float maxHealth = 100; public float currentHealth = 100; private float originalScale; 
Dans 
maxHealth la santé maximale de l'ennemi est stockée, et dans 
currentHealth - la santé restante. Enfin, dans 
originalScale est la taille initiale de la barre de santé.
Enregistrez l'objet 
originalScale dans 
Start() :
 originalScale = gameObject.transform.localScale.x; 
Nous stockons la valeur 
x de la propriété 
localScale .
Définissez l'échelle de la barre d'intégrité en ajoutant le code suivant à 
Update() :
 Vector3 tmpScale = gameObject.transform.localScale; tmpScale.x = currentHealth / maxHealth * originalScale; gameObject.transform.localScale = tmpScale; 
Nous pouvons copier 
localScale dans une variable temporaire car nous ne pouvons pas changer sa valeur 
x séparément. Ensuite, nous calculons la nouvelle échelle 
x en fonction de la santé actuelle du scarabée et 
localScale nouveau la valeur 
localScale à une variable temporaire.
Enregistrez le fichier et lancez le jeu dans Unity. Au-dessus des ennemis, vous verrez des stries de santé.
Pendant le jeu, développez l'un des objets 
ennemis (clone) dans la 
hiérarchie et sélectionnez son 
HealthBar enfant. Modifiez sa valeur de 
santé actuelle et voyez comment sa barre de santé change.
Détection des ennemis à portée
Maintenant, nos monstres doivent savoir quels ennemis viser. Mais avant de réaliser cette opportunité, vous devez préparer Monster et Enemy.
Sélectionnez Project Browser 
Prefabs \ Monster et ajoutez-y le composant 
Circle Collider 2D dans l' 
inspecteur .
Réglez le paramètre 
Rayon du collisionneur sur 
2,5 - cela indiquera le rayon d'attaque des monstres.
Cochez la case 
Est un déclencheur pour que les objets passent à travers cette zone plutôt que d'entrer en collision avec elle.
Enfin, en haut de l' 
inspecteur , définissez la 
couche du monstre sur 
Ignorer Raycast . Dans la boîte de dialogue, cliquez sur 
Oui, modifiez les enfants . Si Ignorer Raycast n'est pas sélectionné, le collisionneur répondra aux événements de clic de souris. Ce sera un problème car les monstres bloquent les événements destinés aux objets Openspot en dessous d'eux.
Pour garantir que l'ennemi est détecté dans la zone de déclenchement, nous devons lui ajouter un collisionneur et un corps rigide, car Unity envoie uniquement des événements de déclenchement lorsqu'un corps rigide est attaché à l'un des collisionneurs.
Dans l' 
arborescence du projet, sélectionnez 
Prefabs \ Enemy . Ajoutez le composant 
Rigidbody 2D et sélectionnez 
Cinématique pour le 
type de corps . Cela signifie que le corps ne sera pas affecté par la physique.
Ajoutez 
Circle Collider 2D avec un 
rayon de 
1 . Répétez ces étapes pour 
Prefabs \ Enemy 2 .
Les déclencheurs sont configurés, de sorte que les monstres comprendront que les ennemis sont dans leur rayon d'action.
Nous devons préparer une dernière chose: un script indiquant aux monstres quand l'ennemi est détruit afin qu'ils ne lèvent pas d'exception tout en continuant à tirer.
Créez un nouveau script 
C # appelé 
EnemyDestructionDelegate et ajoutez-le aux 
préfabriqués Enemy et 
Enemy2 .
Ouvrez 
EnemyDestructionDelegate.cs dans l'IDE et ajoutez la déclaration de délégation suivante:
 public delegate void EnemyDelegate (GameObject enemy); public EnemyDelegate enemyDelegate; 
Ici, nous créons un 
delegate , c'est-à-dire un conteneur pour une fonction qui peut être passée en tant que variable.
Remarque : les délégués sont utilisés lorsqu'un objet de jeu doit notifier activement les autres objets de jeu des modifications. En savoir plus sur les délégués dans la documentation Unity .
Ajoutez la méthode suivante:
 void OnDestroy() { if (enemyDelegate != null) { enemyDelegate(gameObject); } } 
Lorsqu'un objet de jeu est détruit, Unity appelle automatiquement cette méthode et vérifie que le délégué 
null inégalité 
null . Dans notre cas, nous l'appelons avec 
gameObject comme paramètre. Cela permet à tous les répondants enregistrés comme délégués de savoir que l'ennemi est détruit.
Enregistrez le fichier et revenez à Unity.
Nous donnons aux monstres une licence pour tuer
Et maintenant, les monstres peuvent détecter les ennemis dans le rayon de leur action. Ajoutez un nouveau script 
C # au préfabriqué 
Monster et nommez-le 
ShootEnemies .
Ouvrez 
ShootEnemies.cs dans l'EDI et ajoutez-y la construction suivante pour accéder aux 
Generics .
 using System.Collections.Generic; 
Ajoutez une variable pour suivre tous les ennemis à portée:
 public List<GameObject> enemiesInRange; 
Dans 
enemiesInRange nous stockons tous les ennemis à portée.
Initialisez le champ dans 
Start() .
 enemiesInRange = new List<GameObject>(); 
Au tout début, il n'y a pas d'ennemis dans le rayon d'action, nous créons donc une liste vide.
Remplissez la liste d' 
enemiesInRange ! Ajoutez le code suivant au script:
 
- Dans OnEnemyDestroynousOnEnemyDestroyl'ennemi deenemiesInRange. Lorsqu'un ennemi marche sur un déclencheur autour d'un monstre,OnTriggerEnter2DestOnTriggerEnter2D.
- Ensuite, nous ajoutons l'ennemi à la liste enemiesInRangeet ajoutons l'événementOnEnemyDestroy. Nous garantissons donc que lors de la destruction de l'ennemi,OnEnemyDestroysera appelé. Nous ne voulons pas que les monstres dépensent des munitions contre des ennemis morts, non?
- Dans OnTriggerExit2DnousOnTriggerExit2Dl'ennemi de la liste et désenregistrons le délégué. Nous savons maintenant quels ennemis sont à portée.
Enregistrez le fichier et lancez le jeu dans Unity. Pour vous assurer que tout fonctionne, positionnez le monstre, sélectionnez-le et suivez les modifications dans la liste 
enemiesInRange dans l' 
enemiesInRange .
Sélection cible
Les monstres savent désormais quel ennemi est à portée. Mais que feront-ils quand il y aura plusieurs ennemis dans le rayon?
Bien sûr, ils attaqueront celui le plus proche du foie!
Ouvrez le 
script IDE 
MoveEnemy.cs et ajoutez une nouvelle méthode qui calcule ce monstre:
 public float DistanceToGoal() { float distance = 0; distance += Vector2.Distance( gameObject.transform.position, waypoints [currentWaypoint + 1].transform.position); for (int i = currentWaypoint + 1; i < waypoints.Length - 1; i++) { Vector3 startPosition = waypoints [i].transform.position; Vector3 endPosition = waypoints [i + 1].transform.position; distance += Vector2.Distance(startPosition, endPosition); } return distance; } 
Le code calcule la longueur de chemin non encore parcourue par l'ennemi. Pour ce faire, il utilise 
Distance , qui est calculée comme la distance entre deux instances de 
Vector3 .
Nous utiliserons cette méthode plus tard pour découvrir quelle cible attaquer. Cependant, bien que nos monstres ne soient pas armés et impuissants, nous le ferons d'abord.
Enregistrez le fichier et revenez à Unity pour commencer à configurer vos shells.
Donnons des coquilles aux monstres. Beaucoup de coquillages!
Faites glisser depuis l'arborescence du projet vers la scène 
Images / Objets / Bullet1 . Réglez la position sur 
z à 
-2 - les positions sur x et y ne sont pas importantes, car nous les définissons chaque fois que nous créons une nouvelle instance du projectile pendant l'exécution du programme.
Ajoutez un nouveau script 
C # appelé 
BulletBehavior , puis dans l'EDI, ajoutez-y les variables suivantes:
 public float speed = 10; public int damage; public GameObject target; public Vector3 startPosition; public Vector3 targetPosition; private float distance; private float startTime; private GameManagerBehavior gameManager; 
speed détermine la vitesse des projectiles; la 
damage claire d'après le nom.
target , 
startPosition et 
targetPosition déterminent la direction du projectile.
distance et 
startTime suivent la position actuelle du projectile. 
gameManager récompense le joueur lorsqu'il tue l'ennemi.
Attribuez les valeurs de ces variables dans 
Start() :
 startTime = Time.time; distance = Vector2.Distance (startPosition, targetPosition); GameObject gm = GameObject.Find("GameManager"); gameManager = gm.GetComponent<GameManagerBehavior>(); 
startTime . , , 
GameManagerBehavior .
Update() :
 
- , Vector3.Lerp.
- targetPosition, ,- target.
- HealthBar- damage.
- , , .
Unity.
Ne serait-il pas formidable que le monstre commence à tirer plus d'obus à des niveaux élevés? Heureusement, cela est facile à mettre en œuvre.Faites glisser l'objet de jeu Bullet1 de la hiérarchie vers l'onglet Projet pour créer un préfabriqué de projectile. Retirez l'objet d'origine de la scène - nous n'en aurons plus besoin.Dupliquez le préfabriqué Bullet1 deux fois . Nommez les copies de Bullet2 et Bullet3 .Sélectionnez Bullet2 . Dans l' inspecteur, définissez le champ Sprite du composant Sprite Renderer sur Images / Objects / Bullet2 . Bullet2 , Bullet1.
, 
Bullet3 Images/Objects/Bullet3 .
Bullet Behavior , .
Project Bullet1 . 
Inspector Bullet Behavior (Script) , 
Damage 10 Bullet1 , 
15 Bullet2 20 Bullet3 — , .
Remarque : j'ai modifié les valeurs de sorte qu'à des niveaux plus élevés, le prix des dommages augmente. Cela empêche la mise à niveau de permettre au joueur d'améliorer les monstres aux meilleurs points.
Coques préfabriquées - la taille augmente avec le niveauChanger le niveau des obus
Attribuez différents obus à différents niveaux de monstres, afin que les monstres plus forts détruisent les ennemis plus rapidement.Ouvrez MonsterData.cs dans l'IDE et ajoutez aux MonsterLevelvariables suivantes: public GameObject bullet; public float fireRate; 
Nous avons donc réglé le préfabriqué du projectile et la fréquence de tir pour chaque niveau de monstres. Enregistrez le fichier et revenez à Unity pour terminer la configuration du monstre.Sélectionnez le préfabriqué Monster dans Project Browser . Dans l' inspecteur, développez Niveaux dans le composant Monster Data (Script) . Réglez la cadence de tir de chaque élément sur 1 . Définissez ensuite le paramètre Bullet des éléments 0, 1 et 2 sur Bullet1 , Bullet2 et Bullet3 .Les niveaux des monstres doivent être définis comme suit:Les obus tuent les ennemis? Oui! Ouvrons le feu!Feu ouvert
IDE 
ShootEnemies.cs :
 private float lastShotTime; private MonsterData monsterData; 
, , 
MonsterData , , .
Start() :
 lastShotTime = Time.time; monsterData = gameObject.GetComponentInChildren<MonsterData>(); 
lastShotTime MonsterData .
, :
 void Shoot(Collider2D target) { GameObject bulletPrefab = monsterData.CurrentLevel.bullet;  
- . z z bulletPrefab. z , , .
- bulletPrefab- MonsterLevel.- startPosition- targetPosition.
- : , .
. , .
ShootEnemies.cs Update() :
 GameObject target = null;  
.
- . minimalEnemyDistance. , .
- Shoot,- lastShotTime.
- Nous calculons l'angle de rotation entre le monstre et sa cible. Nous faisons tourner le monstre à cet angle. Maintenant, il regardera toujours la cible.
Enregistrez le fichier et lancez le jeu dans Unity. Les monstres commenceront désespérément à protéger les cookies. Nous avons enfin terminé!Où aller ensuite
Le projet terminé peut être téléchargé ici .Nous avons fait un excellent travail dans ce tutoriel et maintenant nous avons un excellent jeu.Voici quelques idées pour poursuivre le développement du projet:- Plus de types d'ennemis et de monstres
- Différentes routes d'ennemis
- Différents niveaux de jeu
Chacun de ces aspects nécessitera des modifications minimes et peut rendre le jeu plus amusant. Si vous créez un nouveau jeu basé sur ce didacticiel, je serai heureux de le jouer, veuillez donc partager un lien vers celui-ci.Des pensées intéressantes sur la création d'un jeu à succès de tower defense peuvent être trouvées dans cette interview .