Construisez Arkanoid avec Unity mécanique de joueur et de balle

Ce que vous allez créer

Dans cette série de didacticiels, nous allons vous montrer comment recréer le jeu classique Arkanoid (ou Breakout) dans Unity, à l'aide des outils 2D natifs de Unity. Dans chaque article, nous nous concentrerons sur une partie spécifique du jeu; dans ce post, nous allons faire avancer la pagaie et la balle.

Où nous nous sommes laissés

Dans le didacticiel précédent, vous avez configuré le projet, importé les ressources et préparé la scène pour le premier niveau. Si vous n'avez pas suivi le didacticiel précédent, nous vous recommandons fortement de le faire avant de commencer celui-ci..

Aperçu final

Jetez un coup d'oeil à cette démo pour voir ce que nous visons dans toute la série:

Et voici ce que nous aurons à la fin de cette partie:

Mouvement du joueur

Vous avez déjà la palette du joueur dans l'interface; maintenant vous devez interagir avec elle. Vous allez le déplacer horizontalement, à gauche et à droite. Afin de créer ce mouvement par entrée, vous devez créer un Scénario.

Les scripts sont des extraits de code de programmation qui effectuent des tâches spécifiques. Unity peut gérer trois langages de programmation: Boo, C # et JavaScript. Tous les scripts créés dans ce tutoriel seront écrits en C # (mais n'hésitez pas à les implémenter dans une autre langue si vous préférez).

 Pour créer un script, allez à votre Projet onglet, sélectionnez le dossier Les scripts, et faites un clic droit dessus pour faire apparaître un menu. Sélectionner Créer> Script C #. Un nouveau fichier appelé NewBehaviourScript apparaîtra; renommer en PlayerScript. dans le Inspecteur onglet, vous verrez le contenu du script lui-même.

Double-cliquez sur le script pour le modifier. MonoDevelop IDE s’ouvrira par défaut, mais vous pouvez configurer un autre éditeur de code pour l’ouvrir si vous préférez..

utiliser UnityEngine; using System.Collections; Classe publique NewBehaviourScript: MonoBehaviour // Utilisez ceci pour l'initialisation void Start ()  // La mise à jour est appelée une fois par image void Update () 

Tous les scripts Unity auront deux méthodes par défaut:

  • Début(): utilisé pour initialiser les variables ou paramètres dont nous avons besoin dans notre code.
  • Mettre à jour(): appelé chaque image du jeu et utilisée pour mettre à jour l'état du jeu.

Pour déplacer le lecteur, vous avez besoin de deux informations:

  • La position du joueur
  • vitesse du joueur

Ainsi, créez deux variables (variables de classe globales) pour stocker ces informations:

public float playerVelocity; joueur privé Vector3;

Comme vous l'avez peut-être remarqué, playerVelocity est une variable publique, alors que La position du joueur est privé. Pourquoi avons-nous fait cela? Eh bien, Unity vous permet de modifier les valeurs des variables publiques dans l'éditeur sans avoir à modifier le code réel. Ceci est très utile lorsque vous avez des paramètres qui doivent être ajustés en permanence. La vitesse est l'un de ces cas, nous le rendons public.

Enregistrez le script (dans MonoDevelop) et accédez à nouveau à l'éditeur Unity..

Vous avez maintenant le script; il vous suffit de l'affecter à l'objet Paddle du joueur. Sélectionnez la palette de la Hiérarchie onglet, et dans le Inspecteur, Cliquez sur Ajouter un composant. Maintenant, tapez le nom du script que vous venez de sauvegarder et ajoutez-le à l'objet du jeu..

Pour plus d'informations sur le concept des composants et leur fonctionnement dans Unity, voir Unity: à présent, vous songez aux composants.

Une autre façon d’ajouter le script au composant serait de le faire glisser de son dossier et de le déposer sur le dossier. Ajouter un composant surface. Vous devriez voir quelque chose comme ça dans votre Inspecteur:

Comme vous pouvez le constater, depuis que nous avons quitté le playerVelocity variable public, vous pouvez maintenant définir sa valeur dans l'éditeur. Pour l'instant, définissez la valeur sur 0,3 et retourner au code.

Vous allez maintenant initialiser le La position du joueur. Pour ce faire, vous devez accéder à la position de l'objet du jeu dans le script Début méthode:

// Utilisez ceci pour l'initialisation void Start () // récupère la position initiale de l'objet de jeu playerPosition = gameObject.transform.position; 

Maintenant nous avons défini le paddle initiale position et la vitesse, mais nous devons toujours le déplacer. Pour cela, nous allons éditer le Mettre à jour méthode. 

Puisque nous voulons seulement objecter pour nous déplacer horizontalement, nous pouvons utiliser le GetAxis méthode du Contribution classe pour trouver la direction dans laquelle l’entrée du joueur pointe le long de l’axe horizontal (-1 pour la gauche, +1 pour la droite), multipliez cette valeur par la vitesse, ajoutez cette valeur à la position X actuelle de la palette et mettez à jour la valeur actuelle. La position du joueur correspondre.

Pendant que nous traitons des entrées, nous voulons également nous assurer que le jeu se termine lorsque le joueur appuie sur le bouton de la souris. Esc clé.

L'extrait complet est ci-dessous:

utiliser UnityEngine; using System.Collections; Classe publique PlayerScript: MonoBehaviour public float playerVelocity; joueur privé Vector3; // Utilisez ceci pour l'initialisation void Start () // récupère la position initiale de l'objet de jeu playerPosition = gameObject.transform.position;  // La mise à jour est appelée une fois par image. Void Update () // mouvement horizontal playerPosition.x + = Input.GetAxis ("Horizontal") * playerVelocity; // quitte le jeu si (Input.GetKeyDown (KeyCode.Escape)) Application.Quit ();  // met à jour l'objet de jeu transform transform.position = playerPosition; 

Enregistrez le script et revenez dans l'éditeur Unity. Maintenant, appuyez sur Jouer et essayez de déplacer le joueur avec les flèches gauche et droite.

Définir la zone de jeu

Vous avez probablement remarqué que la pagaie peut sortir du niveau. Cela se produit car aucune limite n'est définie pour la zone de jeu.. 

Pour créer la limite, créez d'abord une autre variable publique, appelez-la. frontière.

Cette variable stockera la position X maximale vers laquelle la palette peut se déplacer. Puisque nous allons construire le niveau de manière symétrique autour de la position (0, 0, 0), cela signifie que la valeur limite absolue sera la même pour X positif et négatif.

Pour éviter de laisser le joueur franchir la limite, nous allons ajouter quelques si conditions. Fondamentalement, nous dirons que si la valeur x de la position est supérieure à la valeur limite, la valeur x sera définie comme égale à la limite. De cette façon, nous nous assurons que la pagaie ne puisse jamais quitter la zone de jeu. Le code pertinent est ci-dessous: 

utiliser UnityEngine; using System.Collections; Classe publique PlayerScript: MonoBehaviour public float playerVelocity; joueur privé Vector3; limite de flottement publique; // Utilisez ceci pour l'initialisation void Start () // récupère la position initiale de l'objet de jeu playerPosition = gameObject.transform.position;  // La mise à jour est appelée une fois par image. Void Update () // mouvement horizontal playerPosition.x + = Input.GetAxis ("Horizontal") * playerVelocity; // quitte le jeu si (Input.GetKeyDown (KeyCode.Escape)) Application.Quit ();  // met à jour l'objet de jeu transform transform.position = playerPosition; // frontières if (playerPosition.x < -boundary)  transform.position = new Vector3 (-boundary, playerPosition.y, playerPosition.z);  if (playerPosition.x > borne) transform.position = new Vector3 (borne, playerPosition.y, playerPosition.z); 

Maintenant, retournez dans l'éditeur et trouvez le meilleur rapport qualité-prix pour le frontière. En faisant glisser la position de la palette sur l'axe des X, vous pouvez voir que la valeur parfaite est 5,46 (dans notre projet au moins).

dans le Inspecteur, réinitialiser la valeur X de la position de la palette à 0, et entrée 5,46 sur le Frontière paramètre sous le Script de joueur composant.

presse Jouer dans l'éditeur. Maintenant, vous pouvez déplacer la raquette, mais uniquement dans la zone de jeu..

Création de propriétés physiques

Dans ce jeu particulier, nous devons créer des propriétés physiques pour trois composants: la pagaie, la balle et les murs. Puisque nous créons un jeu en 2D, nous utiliserons et appliquerons la 2D collisionneurs. (Un collisionneur est un type de composant particulier qui permet aux objets qui leur sont associés de réagir à d'autres collisionneurs.)

Commencez par ajouter un collisionneur à notre pagaie. dans le Hiérarchie, sélectionnez notre objet paddle. Déplacer vers le Inspecteur, Cliquez sur Ajouter un composant et le type collisionneur. Comme vous pouvez le voir dans la capture d'écran ci-dessous, plusieurs types de collisionneurs sont à votre disposition. Chaque collisionneur a des propriétés spécifiques qui ressemblent à l'objet associé.

Puisque le joueur a un format rectangle, nous allons utiliser le Box Collider 2D. Sélectionnez-le et le composant sera automatiquement ajouté à votre objet joueur. Les valeurs pour la taille et la position centrale du collisionneur sont déjà définies; ces valeurs par défaut fonctionneront pour vous, vous n'avez donc pas besoin de les changer.

Faites maintenant le même processus pour les trois barres et le bloc. (Hiérarchie> Inspecteur> Ajouter un composant> Box Collider 2D).

Tous vos objets de jeu ont maintenant des collisionneurs, attendez-vous au ballon. Comme la balle a une forme différente, vous devrez utiliser un collisionneur différent. Sélectionnez-le et, dans le Inspecteur onglet, ajouter le composant Cercle Collider 2D.

le Cercle Collider 2D est similaire à la Collisionneur de boîte, sauf qu'au lieu de la Taille paramètre qui définit la largeur et la hauteur de la boîte, il a une Rayon paramètre qui définit le rayon du cercle.

Matériel rebondissant

Afin de faire rebondir la balle, nous devons créer un matériau physique qui rebondit et l’attacher à la balle. Unity a déjà créé ce matériel spécifique, nous avons donc besoin de l'ajouter. 

Sur le Projet onglet, créez un nouveau dossier à l'intérieur du Atout dossier et nommez-le La physique. Sélectionnez ce dossier, cliquez sur Créer, et choisir Matériau Physics2D. Nommez votre nouveau matériel de physique BallPhysicsMaterial.

Le matériau a deux paramètres: Friction et Bounciness. Puisque vous voulez un comportement purement rebondi, vous devez modifier les valeurs en conséquence: 0 pour Friction, 1 pour Bounciness.

Maintenant que vous avez le matériel prêt, appliquez-le à la balle. Sélectionnez l'objet de jeu de balle sur le Hiérarchie onglet et passer à la Inspecteur. Si vous regardez de plus près à votre Cercle Collider 2D, vous remarquerez que ce composant a un paramètre appelé Matériel; ici, vous pouvez attacher n'importe quel matériau physique que vous voulez à cet objet.

Pour attacher le BallPhysicsMaterial, il suffit de le sélectionner et de le faire glisser vers le Matériel paramètre sur le collisionneur.

Note de l'éditeur: Cette capture d'écran montre un Box Collider 2D, mais ça devrait être un Cercle Collider 2D.

Ajout d'un corps rigide

Pour que la balle se déplace sous le contrôle de la physique, nous devons ajouter une dernière chose: un composant de corps rigide. Sélectionnez l'objet balle et ajoutez le composant RigidBody 2D. Ce composant a plusieurs paramètres qui peuvent être ajustés. Puisque la balle ne bougera qu’en rebondissant, vous devriez changer le Échelle de gravité paramètre de 1 à 0-De cette façon, nous nous assurons que la balle ne soit pas affectée par la gravité. Le reste des paramètres peut être laissé par défaut:

Programmation de l'objet balle

La balle sera complètement dynamique, nous devons donc créer un script personnalisé pour ce comportement. 

Créez un nouveau script (nous utiliserons à nouveau C #) et nommez-le BallScript. Affectez ce nouveau script à l’objet balle (Hiérarchie> Inspecteur> Ajouter un composant).

Maintenant, analysons les règles et les propriétés de la balle avant de les coder dans le script:

  • La balle devrait avoir deux états: inactif (suit la raquette avant le début de la partie) et actif (rebondit sur la pagaie, les murs et les blocs).
  • La balle ne devient active que lorsque le joueur appuie sur une touche spécifique du clavier.
  • Quand la balle devient active, on lui applique une force pour la faire bouger.
  • Si le ballon tombe de l'écran, il devrait être réinitialisé.

Sur la base de ces informations, nous allons d’abord créer les variables globales. ballIsActive, position de balle, et ballInitialForce.

bool privé ballIsActive; Vector3 ballPosition privé; vecteur privé ball2 InitialForce;

Maintenant que vous avez défini les variables, vous devez initialiser l'objet de jeu. dans le Début méthode, vous devriez:

  • Créer une force pour pousser le ballon.
  • Réglez le ballon sur inactif.
  • Stocker la position du ballon.

Voici à quoi ça ressemble:

void Start () // crée la force ballInitialForce = new Vector2 (100.0f, 300.0f); // défini sur inactif ballIsActive = false; // position de la balle ballPosition = transform.position; 

Ici, nous appliquons une force de 300 le long de l'axe des Y pour faire bouger la balle vers le haut, et 100 le long de l'axe X pour faire bouger la balle en diagonale au lieu de directement vers le haut. De cette façon, vous forcez le joueur à déplacer la position de la raquette.

dans le Mettre à jour méthode, nous allons définir le comportement de la balle Abordons ce cas par cas.

Premièrement, nous devons gérer les entrées de l'utilisateur. nous allons utiliser la valeur par défaut Saut bouton de l'unité comme et touche d'action. La clé associée à Saut peut être changé, mais la valeur par défaut est le Espace barre sur le clavier.

void Update () // vérifie la saisie de l'utilisateur si (Input.GetButtonDown ("Jump") == true) 

La prochaine chose à faire est de vérifier l'état de la balle, car la clé d'action ne devrait fonctionner que lorsque la balle est inactive:

void Update () // vérifie la saisie de l'utilisateur si (Input.GetButtonDown ("Jump") == true) // vérifie si est la première lecture si (! ballIsActive) 

Supposons que ceci est au début du jeu, nous devons donc appliquer une force sur le ballon et le mettre en activité. Le nouveau Mettre à jour méthode devrait ressembler à:

void Update () // vérifie la saisie de l'utilisateur si (Input.GetButtonDown ("Jump") == true) // vérifie si est le premier jeu si (! ballIsActive) // ajoute une force rigidbody2D.AddForce (ballInitialForce ) // set ball active ballIsActive =! ballIsActive; 

À présent, Jouer votre projet et tester le Saut action; vous remarquerez que le ballon est poussé et commence à rebondir comme il se doit. Cependant, vous remarquerez également que la balle ne suit pas la position de la raquette quand elle est inactive. Arrêtez le jeu et changeons cela.

dans le Mettre à jour méthode, nous devons vérifier l'état de la balle et, si la balle est inactive, nous devons nous assurer que la valeur X de la balle est identique à la valeur X de la raquette. 

Ah, mais comment pouvons-nous accéder à la position du joueur si elle se trouve dans un autre objet du jeu? Simple: nous créons simplement une variable d'objet de jeu et y stockons une référence. Donc, ajoutez l'objet paddle en tant que variable globale publique de type GameObject:

bool privé ballIsActive; Vector3 ballPosition privé; vecteur privé ball2 InitialForce; // GameObject public GameObject playerObject;

Retour à la Mettre à jour méthode. Nous allons vérifier l'état de la balle et la référence de la palette. Si l'état est inactif et que l'objet paddle n'est pas null (c'est-à-dire que nous y avons une référence), la balle doit suivre la position de la palette. Le complet Mettre à jour est maintenant:

void Update () // vérifie la saisie de l'utilisateur si (Input.GetButtonDown ("Jump") == true) // vérifie si est le premier jeu si (! ballIsActive) // ajoute une force rigidbody2D.AddForce (ballInitialForce ) // set ball active ballIsActive =! ballIsActive;  if (! ballIsActive && playerObject! = null) // récupère et utilise la position du joueur ballPosition.x = playerObject.transform.position.x; // applique la position du joueur X à la transformation de la balle.position = ballPosition; 

Enregistrez votre script et retournez dans l'éditeur. Comme vous l'avez peut-être remarqué, la référence à la palette est publique, ce qui signifie que vous la passerez à l'éditeur. Sur le Hiérarchie onglet, sélectionnez la balle. dans le Inspecteur, vous remarquerez le Objet Joueur paramètre dans notre script est actuellement Aucun.

Pour en faire une référence à l’objet du jeu paddle du joueur, il suffit de glisser-déposer l’objet du jeu paddle du Hiérarchie au Objet Joueur paramètre dans le script.

Clique le Jouer bouton, et testez votre jeu. Vous verrez maintenant que la balle suivra le joueur avant le Saut la touche est enfoncée.

Réinitialiser le jeu

Il ne vous reste plus qu’une chose à faire pour terminer le script. Comme vous l'avez peut-être remarqué, si le joueur n'attrape pas le ballon, il tombera du jeu et le jeu ne se réinitialisera pas. Modifions le Mettre à jour méthode pour résoudre ce problème. 

Nous vérifierons si la balle est active et si sa position Y est inférieure à -6. Si c'est le cas, nous désactivons le ballon et réinitialisons la position du ballon à la position du joueur. L'extrait de code qui ressemble à ceci:

if (ballIsActive && transform.position.y < -6)  ballIsActive = !ballIsActive; ballPosition.x = playerObject.transform.position.x; ballPosition.y = -4.2f; transform.position = ballPosition; 

Si vous enregistrez le script et vérifiez dans l'éditeur, vous pouvez voir que chaque fois que la balle tombe de l'écran, la position de la balle est repositionnée sur la position du joueur et définie sur inactive. Cependant, si vous commencez à jouer, vous remarquerez un comportement étrange. Chaque fois que la balle tombe, la prochaine fois que vous appuyez sur la touche d'action, sa vitesse augmente. Pourquoi donc? 

Eh bien, rappelez-vous que nous ajoutons une force à la balle lors du lancement. Ainsi, chaque fois que vous réinitialisez le jeu, vous continuez à ajouter de la force au corps rigide, ce qui rend le jeu incroyablement difficile après quelques essais. Alors, la question est, comment pouvons-nous résoudre ce problème?

Afin de garder la même force globale appliquée, nous devons nous assurer que vous supprimez toutes les forces appliquées à la balle chaque fois que vous la réinitialisez. Pour ce faire, nous pouvons simplement activer le Est cinématique paramètre à chaque fois que la balle s’arrête et la désactiver au début du jeu. Ce paramètre détermine si la balle est affectée ou non par la physique. Si vous la désactivez, toutes les forces appliquées auparavant disparaîtront.. 

Ajoutez deux autres lignes à votre Mettre à jour méthode pour faire ceci:

  • rigidbody2D.isKinematic = false avant que la force ne soit ajoutée, et
  • rigidbody2D.isKinematic = true quand on veut que le ballon recommence à bouger.

Au final, la complète Mettre à jour méthode devrait ressembler à ceci:

Classe publique BallScript: MonoBehaviour private bool ballIsActive; Vector3 ballPosition privé; vecteur privé ball2 InitialForce; // GameObject public GameObject playerObject; // Utiliser ceci pour l'initialisation void Start () // créer la force ballInitialForce = new Vector2 (100.0f, 300.0f); // défini sur inactif ballIsActive = false; // position de la balle ballPosition = transform.position;  // Update est appelé une fois par image. Void Update () // vérifie la saisie de l'utilisateur si (Input.GetButtonDown ("Jump") == true) // vérifie si est la première lecture si (! BallIsActive) / / réinitialise la force rigidbody2D.isKinematic = false; // ajoute une force rigidbody2D.AddForce (ballInitialForce); // set ball active ballIsActive =! ballIsActive;  if (! ballIsActive && playerObject! = null) // récupère et utilise la position du joueur ballPosition.x = playerObject.transform.position.x; // applique la position du joueur X à la transformation de la balle.position = ballPosition;  // Vérifie si la balle tombe si (ballIsActive && transform.position.y < -6)  ballIsActive = !ballIsActive; ballPosition.x = playerObject.transform.position.x; ballPosition.y = -4.2f; transform.position = ballPosition; rigidbody2D.isKinematic = true;   

Maintenant vous pouvez Jouer le jeu et vérifier toutes les fonctionnalités implémentées ci-dessus.

La prochaine fois

Ceci conclut la deuxième partie de la série. Vous avez maintenant implémenté des scripts personnalisés, des collisionneurs de physique et des entrées utilisateur programmées. La prochaine fois, nous installerons les blocs.

Si vous avez des questions ou des commentaires sur ce que nous avons couvert jusqu'à présent, veuillez laisser un commentaire ci-dessous..