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.Atan2
pour déterminer l'angle en radians vers lequel newDirection
dirigé (le point zéro est à droite). Multiplie le résultat par 180 / 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
timeInterval
est timeInterval
à timeBetweenWaves
. Sinon, nous vérifions si timeInterval
est timeInterval
aux vagues de spawnInterval
. En tout cas, on vérifie que nous n'avons pas créé tous les ennemis dans cette vague. - Si nécessaire,
enemyPrefab
l'ennemi, créant ainsi une instance d' enemyPrefab
. Augmentez également la valeur des enemiesSpawned
. - 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
CameraShake
pour 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,
gameOver
sur true
et démarrez l'animation gameOver
. - 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
OnEnemyDestroy
nous OnEnemyDestroy
l'ennemi de enemiesInRange
. Lorsqu'un ennemi marche sur un déclencheur autour d'un monstre, OnTriggerEnter2D
est OnTriggerEnter2D
. - Ensuite, nous ajoutons l'ennemi à la liste
enemiesInRange
et ajoutons l'événement OnEnemyDestroy
. Nous garantissons donc que lors de la destruction de l'ennemi, OnEnemyDestroy
sera appelé. Nous ne voulons pas que les monstres dépensent des munitions contre des ennemis morts, non? - Dans
OnTriggerExit2D
nous OnTriggerExit2D
l'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 MonsterLevel
variables 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 .