Bouw Arkanoid met eenheid blokmechanica, prefabs en niveauontwerp

Wat je gaat creëren

In deze tutorialserie laten we u zien hoe u het klassieke Arkanoid (of Breakout) -spel in Unity kunt recreëren, met behulp van de eigen 2D-hulpmiddelen van Unity. In elke post zullen we ons concentreren op een specifiek deel van het spel; in dit bericht behandelen we de blokmechanica en de creatie van Prefabs.

Waar we gebleven zijn

In de vorige tutorials hebt u het project opgezet en het gedrag van de paddle en de bal gecodeerd. Als je de vorige tutorials nog niet hebt voltooid, raden we je ten zeerste aan dit te doen voordat je verdergaat.

Laatste voorbeeld

Bekijk deze demo om te zien waar we naar streven in de hele serie:

En hier is wat we zullen hebben aan het einde van deze post:

Het blokscript maken

Op dit moment zijn bijna alle basismechanismen gereed. Het ontbrekende deel is gerelateerd aan het blokobject. Omdat blokken een belangrijk en actief onderdeel van het spel zijn, moeten we er een aangepast script voor maken. 

Het blokscript moet informatie bevatten over:

  • Totaal aantal treffers die het aankan.
  • Punten om te belonen bij het breken.

(Merk op dat het aantal treffers en punten kan veranderen afhankelijk van de blokkleur.) Laten we op basis hiervan het blok drie variabelen geven:

  • Een variabele om het aantal hits op te slaan dat in het blok kan worden opgeslagen.
  • Een variabele om de scorewaarde van het blok op te slaan.
  • Een variabele om het aantal keren op te slaan dat het blok heeft nu al geraakt.

De eerste twee zullen zijn openbaar, aangezien u hun waarden misschien in de editor wilt wijzigen. De derde zal zijn privaat, omdat het alleen voor intern gebruik is. 

Maak dus een nieuw script genaamd BlockScript. Definieer die variabelen en initialiseer het aantal hits naar 0:

public class BlockScript: MonoBehaviour public int hitsToKill: public int points; privé int nummerOfHits; // Gebruik dit voor initialisatie ongeldig Start () numberOfHits = 0;  // Update wordt eenmaal per frame ongeldig Update () 

De volgende stap is om te detecteren wanneer de ballen een blok raken. Wanneer deze botsing plaatsvindt, controleren we of het blok genoeg keer is geraakt om te worden vernietigd, of dat het nog steeds intact is. Daarvoor kunnen we een specifieke methode gebruiken genaamd OnCollisionEnter2D, die elke keer dat er een botsing plaatsvindt met uw object wordt genoemd.

Om te controleren of deze botsing tussen de bal en het blok zit, moeten we dat doen label het balobject. Selecteer de bal in de editor in de Hiërarchie tab en vervolgens de Inspecteur. Op de top van de Inspecteur, net onder de naam van het game-object, is er een veld met de naam Label dat is momenteel gedefinieerd als untagged. Klik op de knop en er verschijnt een vervolgkeuzemenu met de verschillende tagmogelijkheden:

We willen een specifiek label voor de bal, dus sla Tag toevoegen om een ​​nieuwe tag te maken. Nadat u op de optie hebt gedrukt, verschijnt er een nieuwe interface:

Voor deze zelfstudie concentreren we ons alleen op de Element 0 eigendom. Dit definieert de naam van de tag, dus typ de naam Bal erin.

Nu dat je het nieuwe hebt Bal label, wijzig de tag van het ball-object in Bal.


Open de BlockScript bestand zodat we het kunnen coderen OnCollisionEnter2D methode. Om het balspelobject te identificeren, controleert u of de tag met het game-object dat is Bal; zo ja, dan was de botsing tussen het blok en de bal. Voeg de volgende code toe aan uw script.

 void OnCollisionEnter2D (Collision2D-botsing) if (collision.gameObject.tag == "Ball") 

Nu kun je botsingen met de bal detecteren. Bij elke botsing willen we de record verhogen van het aantal keren dat het blok werd geraakt en, als het aantal keren dat het blok werd geraakt hetzelfde is als het maximale aantal treffers dat het blok kan nemen, vernietig het blok. Voor de laatste kunnen we de methode Vernietigen gebruiken.

 De bijgewerkte OnCollisionEnter2D om dit te doen ziet het er als volgt uit:

 void OnCollisionEnter2D (Collision2D-botsing) if (collision.gameObject.tag == "Ball") numberOfHits ++; if (numberOfHits == hitsToKill) // vernietig het object Destroy (this.gameObject); 

Voeg nu de BlockScript naar de Bal voorwerp (Hiërarchie> Inspecteur> Component toevoegen):

Het is nu tijd om te controleren of alles in orde is. Verander de Hits To Kill waarde in de editor voor 1 en Spelen het spel. Wanneer de bal het blok raakt, moet het blok verdwijnen.

Een Prefab maken

Nu de blokmechanica gereed is, vullen we het niveau in. Aangezien je hiervoor meerdere blokken gebruikt, is dit een goed moment om Unity's te introduceren prefabs

Een Prefab is een herbruikbaar spelobject dat meerdere keren in dezelfde scène kan worden ingevoegd. Kort gezegd betekent dit dat als je bijvoorbeeld de waarde van punten van de blauwe blokken wilt wijzigen, je dit niet voor elk blauw blok op de scène hoeft te doen: als je een Prefab hebt van een blauw blok, u past gewoon de Prefab-waarde aan en alle blokken op de scène zullen worden bijgewerkt.

Om een ​​Prefab voor de blauwe blokken te maken, begint u met het hernoemen van de Blok bezwaar tegen Blue Block. Maak vervolgens een nieuwe map in de Middelen map genoemd prefabs. Sleep nu het Blauwe blokken object in de nieuwe map.

Zoals je misschien hebt gemerkt, is het kubuspictogram aan de bovenkant van de Inspecteur is nu blauw. Ook de naam van het game-object in de scène Hiërarchie is ook blauw. Dit betekent dat het blok nu een Prefab is. Heel eenvoudig, toch? Vanaf nu zal het selecteren van de Prefab en het wijzigen van de waarden van toepassing zijn op elke wijziging die u aanbrengt in de parameters van al onze blauwe blokken.

Om de Prefab te testen, sleept u hem van de map naar onze Hiërarchie tab. Zoals u kunt zien, hebben we nu twee blauwe blokken, maar ze delen dezelfde positie, die werd gedefinieerd door de Prefab.

Als u de twee blokken in verschillende posities wilt hebben, selecteert u een van de blokken in de Hiërarchie tab en verplaats het rond de scène. Op deze manier wijzigt u de waarden van die specifieke kopie van het blok en niet alle blokken.

Jij kan Spelen het spel en test de Prefabs.

Prefabs herscheppen

Nu maakt u de resterende Prefabs voor de andere blokken (groen, geel en rood). De belangrijkste stappen voor elk zijn:

  1. Maak een nieuwe Sprite.
  2. Voeg de bijbehorende afbeelding toe.
  3. Voeg een Box Collider 2D toe.
  4. Voeg de BlockScript toe.
  5. Geef het een naam.
  6. Maak een Prefab.

Uiteindelijk zou je vier verschillende Prefabs moeten hebben (één voor elk type blok):

Om de gameplay interessanter te maken, wijzigt u de Hits To Kill voor elk type blok zoals dat:

  • Blauw: 1 raken.
  • Groen: 2 treffers.
  • Geel: 3 treffers.
  • Rood: 4 treffers.

Voeg enkele blokken toe en Spelen het spel; controleer of alles werkt zoals verwacht.

Level ontwerp

Het is nu tijd om je eerste niveau te creëren. Gebruik de Prefabs om het spelgebied te vullen met verschillende blokken. Als je zoveel blokken hebt geplaatst als wij, je Hiërarchie tab is waarschijnlijk overbevolkt met block-game-objecten! Om uw project overzichtelijk te houden, maken we lege game-objecten voor de vier soorten blokken en groeperen we de blokken op kleur:

Op dit punt is je game bijna klaar, je basismechanica is geïmplementeerd en deze moet lijken op de volgende figuur:

Score en levenssysteem

Het score- en levenssysteem is een manier om de spelers te testen en nieuwe dynamiek in games te introduceren. Op dit moment heeft je spel geen mogelijkheid voor spelers om te vorderen of te verliezen. Laten we dat nu veranderen. 

Open de PlayerScript en voeg twee variabelen toe: één voor score en één voor het aantal levens dat de speler heeft. We laten de speler het spel starten met drie levens en geen punten:

private int playerLives; private int playerPoints; // Gebruik dit voor initialisatie ongeldig Start () // verkrijg de beginpositie van het spelobject playerPosition = gameObject.transform.position; playerLives = 3; playerPoints = 0; 

We hebben een methode nodig die het aantal punten verhoogt dat de speler heeft telkens wanneer hij een blok vernietigt. Maak een nieuwe methode genaamd addPoints om dit te doen:

void addPoints (int points) playerPoints + = points; 

Nu hebben we de nieuwe methode die een waarde verwacht, maar hoe deze wordt ontvangen? Er zijn te veel blokken om verwijzingen naar het peddelobject van de speler in elke ...  

De beste manier om dit op te lossen, is door een bericht van het blokobject naar het paddle-object te verzenden. Hoe doen we dat? Nou, eerst moet je de peddel taggen (Hiërarchie> Inspecteur> Tag) met de Speler label.


Met de getagde paddle is het tijd om naar het blokscript te gaan, waar we de methode zullen veranderen OnCollisionEnter2D om de punten naar het spelerobject te sturen: voordat het blok wordt vernietigd, gaan we op zoek naar een spelobject met de Speler tag met behulp van de FindGameObjectsWithTag methode; hierdoor wordt een array van overeenkomende objecten geretourneerd, ans omdat er maar één object met die tag is, weten we dat het object op positie 0 van de geretourneerde array het paddle-object van de speler is.

Nu je de spelersreferentie hebt, kun je deze een bericht sturen met behulp van de Bericht versturen methode. Hiermee kun je een specifieke methode van het spelerobject aanroepen - in dit geval de addPoints methode. 

Het volgende fragment laat zien hoe dit allemaal werkt:

void OnCollisionEnter2D (Collision2D-botsing) if (collision.gameObject.tag == "Ball") numberOfHits ++; if (numberOfHits == hitsToKill) // krijg referentie van spelerobject GameObject player = GameObject.FindGameObjectsWithTag ("Player") [0]; // stuur bericht player.SendMessage ("addPoints", punten); // vernietig het object Destroy (this.gameObject); 

Het volgende dat we moeten doen is de Prefabs bewerken en specifieke puntwaarden geven voor elk type blok. U kunt de volgende waarden gebruiken:

  • Blauw: 10 points;
  • Groen: 20 points;
  • Geel: 35 points;
  • Rood: 50 points;

Laten we nu deze punten en levens in de spelinterface laten zien. Maak in het spelerscript een methode genaamd OnGUI. Deze methode presenteert de GUI van je spel; het is een van de basismethoden om informatie in het speelveld te presenteren. (Let op de hoofdlettergevoelige karakters).

Om de punten en levens te presenteren, moeten we een Label met de gewenste tekst. In de PlayerScript, voeg het toe OnGUI methode, en maak dit label erin:

void OnGUI () GUI.Label (nieuwe Rect (5.0f, 3.0f, 200.0f, 200.0f), "Live's:" + playerLives + "Score:" + playerPoints); 

Je kan nu Spelen de game en het label worden links bovenaan op het scherm weergegeven. U hebt de weergave van lives en punten echter nog niet geprogrammeerd om dienovereenkomstig bij te werken! 

Gebruik hetzelfde PlayerScript, voeg het volgende toe TakeLife methode. De methode trekt slechts één levensduur van de spelerspool af telkens wanneer deze wordt genoemd:

void TakeLife () playerLives--; 

Ga ten slotte naar de BallScript, en in het gedeelte waar je controleert of de bal van het scherm is gevallen, stuur je een bericht naar het spelerobject met de TakeLife methode. Het volledige fragment wordt hieronder weergegeven:

// Controleer of de bal valt als (ballIsActive && transform.position.y < -6)  ballIsActive = !ballIsActive; ballPosition.x = playerObject.transform.position.x; ballPosition.y = -4.2f; transform.position = ballPosition; rigidbody2D.isKinematic = true; // New code - Send Message playerObject.SendMessage("TakeLife"); 

Speel je spel en controleer of het score- en livesysteem werkt zoals verwacht.

De volgende keer

Dit is het derde bericht in de serie. De basisgame-mechanica is op zijn plaats, dus de volgende keer zullen we audio en nieuwe niveaus toevoegen en het voltooide spel inzetten.

Als je vragen of feedback hebt over wat we tot nu toe hebben behandeld, kun je hieronder een reactie achterlaten.