Pong! : Stap 4

Stap 4 : De besturing van de spelers programmeren

Tot nu toe ben je alleen bezig geweest met klik en sleep acties in Unity om objecten te verplaatsen en je hebt daarmee al een heel pong level gemaakt. Dit alles zonder te hoeven programmeren.
Voor de besturing echter is dit wel nodig. Wees gerust want voor een basis Pong spel zijn in het begin maar een paar regels code nodig. Je hoeft het nu niet eens zelf te typen als je weet hoe je tekst kunt kopiëren/plakken, maar het is een goede oefening.
De regels code schrijf je in een ‘script’ bestand, wat eigenlijk gewoon een tekst bestand is maar dan met codetaal in plaats van praattaal.
In Unity wordt de industriële programmeertaal C# (see sharp) gebruikt, wat een uitstekende programmeertaal is voor het programmeren van games, maar C# wordt over over de hele wereld ook gebruikt voor het programmeren van allerlei andere soorten software.
Deze tutorial gaat verder niet diep in op hoe de programmeertaal* werkt, het gaat nu vooral om de ervaring en zodat je ziet hoe het ongeveer in zijn werk gaat in Unity met het maken van nieuwe scripts.

(* Je kunt eigenlijk beter spreken van een programmeer “taal”, met aanhalingstekens, want je hoeft het alleen te leren schrijven, niet uit te spreken, het is dus makkelijker te leren dan een volledige spreektaal)

Klik met je rechter muisknop in de lege Scripts map in de Project view en selecteer Create > C# Script in het rechtermuis-menu:

Verander de naam van het script van NewBehaviourScript naar ‘Player1Controller’ (speler 1 besturing).
Dit kan ook met het rechtermuis-menu ‘Rename’:

Dubbelklik op het script bestand in de Project view om het te openen, een ander programma genaamd Visual Studio (of Visual Studio Code) zal automatisch openen. Dit is het code-schrijf programma dat Unity standaard gebruikt.

Controleer of je in regel 5 achter ‘public class‘ de naam van je script ziet staan, dus ‘Player1Controller’, zo niet verander dan de naam NewBehaviourScript in Player1Controller want anders krijg je meteen een rode error te zien in de Console view:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Player1Controller : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

Maak wat meer ruimte tussen de twee krulhaakjes { } die je onder Update () ziet staan door met je muis achter het eerste krulhaakje te klikken en een keer of 3 op Enter te drukken:

// Update is called once per frame
void Update()
{




}

Tijdens het schrijven van code zul je merken dat het programma je wil helpen met het schrijven van codes door met suggesties te komen in de menuutjes die open springen.
Dit wordt ‘Intellisense’ genoemd en is eigenlijk hetzelfde als de autofill die je ook in gewone schrijfprogramma’s hebt zoals word maar dan speciaal voor code.
Je kan daarmee snel woorden afmaken door met je pijltjestoetsen het woord dat je af wilt maken te selecteren en daarna op Spatie of Enter te drukken of je kunt het negeren en gewoon verder typen:

Typ, of kopieer en plak, de blauwe regels hieronder in de lege ruimte die je net tussen de krulhaakjes hebt gemaakt, dus tussen de {} krulhaakjes van de Update() functie.
(Iets verder omlaag op deze pagina staat het volledige script)

Gebruik steeds de Tab toets om te zorgen dat iedere regel die je binnenin de Update() functie tussen de {} krulhaakjes typt ‘geïndenteerd’ wordt (in het engels heet dit indentation) om te zorgen dat de code makkelijk leesbaar blijft en er goed te zien is welke regels er binnen welk codeblok staan.
Zoals je hieronder ziet is de regel die begint met transform.position, tussen de krulhaakjes van het if-statement codeblok, twee keer met de tab toets geïndenteerd, omdat deze regel eerst binnenin de Update() functie en daarna binnenin het if-statement staat.

Let ook op hoofdletters want C# is case sensitive! (hoofdletter gevoelig):

// Update is called once per frame
void Update()
{    
    if (Input.GetKey(KeyCode.W) == true)
    {
        transform.position = transform.position + Vector3.forward * Time.deltaTime * 5;
    }
}

Misschien kun je al een klein beetje uit de code opmaken wat deze regels doen, namelijk de speler naar voren bewegen als je op de ‘W’ toets drukt.

Om de speler ook naar achteren te kunnen bewegen hoef je eigenlijk alleen dezelfde regels code nog een keer te typen of te kopiëren/plakken en er twee dingetjes aan te veranderen.
De letter ‘S’ achter Keycode, en het woordje ‘back’ achter ‘Vector3′:

// Update is called once per frame
void Update()
{    
    if (Input.GetKey(KeyCode.W) == true)
    {
        transform.position = transform.position + Vector3.forward * Time.deltaTime * 5;
    }

    if ( Input.GetKey(KeyCode.S) == true )
    {
        transform.position = transform.position + Vector3.back * Time.deltaTime * 5;
    }
}

Als het goed is ziet het volledige script er nu zo uit:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Player1Controller : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetKey(KeyCode.W) == true)
        {
            transform.position = transform.position + Vector3.forward * Time.deltaTime * 5;
        }

        if (Input.GetKey(KeyCode.S) == true)
        {
            transform.position = transform.position + Vector3.back * Time.deltaTime * 5;
        }
    }
}

In gewone taal (pseudo code) staat er eigenlijk:
“Als de W toets ingedrukt wordt verplaats dan het object 5 meter per seconde naar voren”
en
“Als de S toets ingedrukt wordt verplaats dan het object 5 meter per seconde naar achteren”.

Voor nu is dit alle code die we nodig hebben voor speler 1.
Voor speler 2 maken we precies hetzelfde script met alleen andere codes voor de knopjes van de besturing!

Druk in Visual Studio op Ctrl + S om het script op te slaan en keer daarna terug naar Unity.
Unity zal steeds nadat je een script hebt gewijzigd en opgeslagen de code controleren op grammatica fouten dus je zult merken dat Unity misschien een paar seconden bezig is voor je weer verder kunt.

(Het kan zijn dat je een rode waarschuwing te zien krijgt in de Console view, in dat geval heb je iets niet goed getypt in je script. Lees in dat geval je code nog een keer na en let goed op hoofdletters en punten/komma’s.
Je kunt ook op de rode waarschuwing in de Console View dubbelklikken. Unity schakelt dan automatisch over naar Visual Studio en laat zien in welke regel de fout zit!)

Klik op het ‘Player1Controller’ script in de Project view en klik daarna bovenin Unitye in de menubalk op Edit > Duplicate om een kopie van het script te maken.

Verander de naam van het gedupliceerde script in ‘Player2Controller’ en dubbelkik erop om het script te openen en weer naar Visual Studio over te schakelen:

Verander in Visual Studio de naam van de script ‘class’ in regel 5, zodat deze overeen komt met de naam van je script, dus ‘Player2Controller’:

public class Player2Controller : MonoBehaviour {

Verander in de twee if-statements codeblokken de woorden ‘KeyCode.W‘ en ‘KeyCode.S‘ naar ‘KeyCode.UpArrow‘ en ‘KeyCode.DownArrow‘:

void Update()
{
    if (Input.GetKey(KeyCode.UpArrow) == true)
    {
        transform.position = transform.position + Vector3.forward * Time.deltaTime * 5;
    }

    if ( Input.GetKey(KeyCode.DownArrow) == true )
    {
        transform.position = transform.position + Vector3.back * Time.deltaTime * 5;
    }
}

Sla het script op met Ctrl + S en keer weer terug naar Unity.

Je hebt nu de code scripts gemaakt voor de besturing van beiden spelers zodat twee spelers tegen elkaar pong kunnen spelen op één keyboard.
De volgende stap is om de scripts als  het ware ‘vast te maken’ aan de twee spelers’ GameObjecten/paddles.
Een script in Unity gaat namelijk pas werken als het een een GameObject in je scene/level vast zit.

Klik op Player (1) in de Hierarchy view om deze te selecteren.
Klik daarna helemaal onderaan in de Inspector view op ‘Add Component’ en selecteer Scripts > Player1Controller uit de lijst.
(Je kunt het Player1Controller script ook op het Player (1) GameObject in de Hierarchy view slepen om het eraan vast te maken, het kan dus op twee manieren.)

Het script zal net als het Rigidbody component van de UnityBasics tutorial aan het object vast komen te zitten:

Doe hetzelfde voor Player (2) met het ‘Player2Controller’ script, dus klik op Player (2) in de Hierarchy view. Daarna ‘Add Component’ in de Inspector view en kies Scripts > Player2Controller.

Druk daarna bovenaan in het midden van Unity op de Play knop om te testen of allebei de spelers bewegen als je op de W, S, en omhoog/omlaag pijltjes toetsen drukt. Unity zal automatisch overschakelen naar de Game view als je op Play drukt:

Zoals je misschien merkt is er een probleem, de spelers paddles gaan dwars door de muren van het level heen als je te ver omhoog of omlaag beweegt.
Dit kun je oplossen door de if-statements in het script iets aan te passen.

Druk nogmaals op Play om het spel weer te stoppen.

Open de Player1Controller en Player2Controller scripts in Visual Studio en verander de if-statements in allebei de scripts als volgt:

void Update()
{
    if (Input.GetKey(KeyCode.W) == true && transform.position.z < 3.75f)
    {
        transform.position = transform.position + Vector3.forward * Time.deltaTime * 5;
    }

    if (Input.GetKey(KeyCode.S) == true && transform.position.z > -3.75f)
    {
        transform.position = transform.position + Vector3.back * Time.deltaTime * 5;
    }
}

In gewone taal staat er nu:
“Als de W toets ingedrukt wordt en de spelers positie op de Z-as kleiner is dan 3.75 plaats dan het object 5 meter per seconde naar voren”
en
“Als de S toets ingedrukt wordt en de spelers positie Z-as groter is dan -3.75 plaats dan het object 5 meter per seconde naar achteren”.

Het dubbele && teken betekent in C# ‘and‘.
De twee angle brackets <> staan voor ‘less than‘ en ‘greater than‘.

Zo zorg je er voor dat de spelers nooit door de muur kunnen bewegen!

Sla de allebei de scripts apart op met Ctrl+S en keer terug naar Unity om het te testen door weer op Play te drukken.
Sla daarna ook het level in Unity op met Ctrl+S !

Ga verder naar Stap 5: De bal laten bewegen