Pong! (Deel 2) Stap 8: Extra

Extra

Het PongBalGedrag script verbeteren

De Pong bal wordt na het starten van de game en iedere keer als er opnieuw geserveerd wordt willekeurig een kant op geschoten dankzij de regels code in het Start () gedeelte van het PongBalGedrag script.

De eerste regel in Start () draait de bal in een willekeurige richting tussen de 0 en 360 graden met de Transform.Rotate() en de Random.Range() functies.
In plaats van drie getallen voor x,y en z in de Transform.Rotate () functie te stoppen wordt er voor het tweede getal, de y-as, een random getal gebruikt.

De tweede regel duwt de bal als het ware naar voren door middel van de AddForce() functie:

public class PongBalGedrag : MonoBehaviour 
{
    // Use this for initialization
    void Start () 
    {
        transform.Rotate(0, Random.Range(0,360), 0);
        GetComponent<Rigidbody>().AddForce( transform.forward * 500 );
    }

De bal een random richting opdraaien is de meest basic manier, maar daardoor kan de bal soms te recht omhoog of omlaag geschoten worden, zoals je vast al gemerkt hebt:

Je zou dit voor de helft op kunnen lossen door de een random getal tussen de 30 en 330 graden te gebruiken, zodat de bal in ieder geval niet recht omhoog kan gaan, maar dan kan de bal nog steeds recht naar onderen worden geschoten.
Wat je kunt doen is eerst twee random getallen uit twee verschillende ranges creëeren en daarna een derde random getal tussen 0 en 100 gebruiken om met 50% kans tussen de eerste twee random getallen te kiezen.
De code hieronder in start doet precies dat. Eerst worden 3 random getallen gemaakt, daarna checkt de if-statement of het derde random getal kleiner is dan 50. Zo ja, dan wordt de bal in de stand van random getal 1 gedraaid, zo niet dan in de stand van random getal 2.
Zo wordt de bal dus even vaak naar links als naar rechts geschoten, maar niet recht omhoog of omlaag!:

public class PongBalGedrag : MonoBehaviour 
{
    // Use this for initialization
    void Start () 
    {
        int randomGetal1 = Random.Range (30, 150);
        int randomGetal2 = Random.Range (210, 330);
        int randomGetal3 = Random.Range (0,100);

        if (randomGetal3 < 50) 
        {
            transform.Rotate (0, randomGetal1, 0);
        } 
        else 
        {
            transform.Rotate (0, randomGetal2, 0);
        }

        GetComponent<Rigidbody>().AddForce( transform.forward * 500 );
    }

Een andere manier waarop je het serveer probleem op zou kunnen lossen is door een lijstje (Array of List) te maken met daarin vaste standen waarin de bal geschoten mag worden. Je zou dan in plaats van een random getal voor de stand uit Random.Range() te gebruiken een random getal als een kaart uit die lijst kunnen ‘trekken’. In de code hieronder wordt eerst een variabel gemaakt met de naam randomStand en van het type int[Array], dus een lijstje met ruimte voor gewone integere getallen. Daarna wordt de Random.Range () functie gebruikt om een willekeurig getal uit de lijst te kiezen:

Dit zijn twee manieren waarop je het serveer probleem op kunt lossen, de eerste manier is wat meer willekeurig omdat het aantal random standen waarin de bal geschoten kan worden groter is dan van manier 2 maar met manier 2 heb je weer meer controle over welke richtingen de bal op kan gaan. Beide manieren maken van de Random.Range () functie gebruik. Het leuke van random getallen is dat je ermee voor meer onvoorspelbaarheid kunt zorgen!

Quit game button

Om een Quit knop te maken waarmee je de game vanuit het hoofdmenu ook kunt sluiten, hoef je, nu je het canvas en het script al hebt gemaakt, slechts een paar dingen te doen..

Open het PlayButton Script en schrijf daarin een nieuw QuitGame () functie, onder de LoadLevel () functie:

using UnityEngine;
using System.Collections;
using UnityEngine.SceneManagement;

public class PlayButton : MonoBehaviour 
{
    public void LoadLevel ()
    {
        SceneManager.LoadScene(Level 1);
    }

    public void QuitGame () 
    {
        Application.Quit();
    }
}

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

Klik met je rechter-muisknop op het Canvas in de Hierarchy View en maak er nog een tweede Button aan vast. Verander de positie van de knop op de Y-as in de Inspector View om deze recht onder de Play knop te plaatsen:

Verder kun je deze button op dezelfde manier instellen als de Play Button, dus door de text van de Button te veranderen naar “Quit” en door het LeegObject in de Button in te stellen.

Om de Quit Button de QuitGame () functie te laten gebruiken i.p.v de LoadLevel () functie kies je nu voor de QuitGame() functie in het On Click () gedeelte:

!Let op: de Quit button werkt alleen als je een “build” van je game speelt, dus niet als je het in Unity speelt.

Pauze functie

Het is natuurlijk wel prettig als je een spel op pauze kunt zetten en de makkelijkste manier om dat te doen is door simpelweg de tijd in het spel stil te zetten..

Open de ‘Level 1’ Scene door erop te dubbelklikken in de Project View.

Maak een nieuw script, bijvoorbeeld met de naam ‘GameManager’ en maak dat script vast aan een nieuw Empty GameObject met bijvoorbeeld dezelfde naam:

Open het GameManager script door erop te dubbelklikken en zorg ervoor dat het script er in zijn geheel zo uitziet:

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

public class GameManager : MonoBehaviour {

    // Use this for initialization
    void Start () {
        
    }
    
    // Update is called once per frame
    void Update () 
    {
        if ( Input.GetKeyDown(KeyCode.P) ) 
        {
            if (Time.timeScale == 1) 
            {
                Time.timeScale = 0;
            } 
            else 
            {
                Time.timeScale = 1;
            }
        }
    }
}

Sla het script op met Ctrl+S en klik in Unity op Play om het te testen.

De logica van dit script is als volgt; Ieder frame, in Update, checkt het script of de P toets wordt ingedrukt. Als dat zo is, dan pas checkt het script of de tijd op 1 (100%) staat.
Als de tijd op 1 staat dan zet het script de tijd op 0, dus op pauze. Anders (else) als de tijd niet op 1 staat, dan staat het spel dus al op pauze en wordt de tijd weer terug op 1 gezet.

Je ziet hier een simpel voorbeeld van een ‘nested’ if-statement. Met nested wordt bedoeld dat de if-statement binnen een andere if-statement is geplaatst in plaats van eronder.

Leuk om te weten is dat je de time scale ook bijvoorbeeld op 0.5 kunt zetten om de tijd langzamer te laten gaan, of op 2 om de tijd sneller te laten gaan. In veel games wordt de time scale gebruikt om slowmotion of ‘bullet-time’ effecten toe te passen!
Als je dat uit wilt proberen zet dan bijvoorbeeld de time scale op 0.5f (de ‘f’ van float) in plaats van op 0:

Time.timeScale = 0.5f;

3D Title Scene

Hou in gedachten dat je de Title Scene in dezelfde 3D ruimte maakt als de gewone levels en je dus ook 3D objecten etc. in je menu kan verwerken, bijvoorbeeld op de achtergrond:

Het voorbeeld hierboven maakt gebruik van 3D objecten achter het UI Canvas en het UI Canvas is ingesteld op ‘World Space’ in plaats van op ‘Screen space – Overlay’ waardoor het niet meer vast zit aan de Camera maar een plaats heeft in de 3D ruimte, net als de andere 3D objecten:

3D objecten als knoppen gebruiken in plaats van 2D UI Buttons kan ook, als je voor het knop object een script schrijft dat gebruik maakt van de OnMouseDown () functie.
Kijk op deze pagina voor het officiële Unity uitleg filmpje over deze functie: https://www.youtube.com/watch?v=DgpHOTuUJ58
En op deze pagina voor de uitleg in de Unity scripting handleiding:
https://docs.unity3d.com/2017.1/Documentation/ScriptReference/MonoBehaviour.OnMouseDown.html

!Let op, de Application.LoadLevel () functie staat tegenwoordig in de SceneManagement.SceneManager class, zoals eerder in deze tutorial is uitgelegd en niet meer in de Application class.
In de uitleg op de website staat misschien nog de oude code. Gebruik het code voorbeeld van hieronder in plaats van het voorbeeld op de site.

using UnityEngine;
using System.Collections;
using UnityEngine.SceneManagement;

public class ExampleClass : MonoBehaviour
{
    void OnMouseDown()
    {
        SceneManager.LoadScene(Level 1);
    }
}

GreenArrowLeft Stap 7

Advertisements

Powered by WordPress.com.

Up ↑

%d bloggers like this: