Unity – Object Oriented Programming – OOP

OOP is the best way to organize your data.

NOTICE:
‘public class SingleCharacterScript’ -> deve avere lo stesso nome dello script senza l’estensione ‘SingleCharacterScript.js’

La classe è un contenitore per variabili e funzioni, ad esempio ‘public class Stuff’ contiene variabili e funzioni, è un buon modo per raggruppare cose che funzionano insieme.

Programmare in OOP significa dividere uno script in più script, ogniuno dei quali si occupa di uno specifico compito.

Qui sotto abbiamo:
– una porzione di codice ‘public class Stuff’ che contiene solo l’inventario dei proiettili, granate, missili.
– una per il movimento ‘function Movement ()’
– una per lo sparo ‘function Shoot ()’

Single Script

SingleCharacterScript.js

#pragma strict

public class SingleCharacterScript extends MonoBehaviour
{
    public class Stuff
    {
        public var bullets : int;
        public var grenades : int;
        public var rockets : int;
        
        public function Stuff(bul : int, gre : int, roc : int)
        {
            bullets = bul;
            grenades = gre;
            rockets = roc;
        }
    }
    
    
    public var myStuff : Stuff = new Stuff(10, 7, 25);
    public var speed : float;
    public var turnSpeed : float;
    public var bulletPrefab : Rigidbody;
    public var firePosition : Transform;
    public var bulletSpeed : float;
    
    
    function Update ()
    {
        Movement();
        Shoot();
    }
    
    
    function Movement ()
    {
        var forwardMovement : float = Input.GetAxis("Vertical") * speed * Time.deltaTime;
        var turnMovement : float = Input.GetAxis("Horizontal") * turnSpeed * Time.deltaTime;
        
        transform.Translate(Vector3.forward * forwardMovement);
        transform.Rotate(Vector3.up * turnMovement);
    }
    
    
    function Shoot ()
    {
        if(Input.GetButtonDown("Fire1") && myStuff.bullets > 0)
        {
            var bulletInstance : Rigidbody = Instantiate(bulletPrefab, firePosition.position, firePosition.rotation);
            bulletInstance.AddForce(firePosition.forward * bulletSpeed);
            myStuff.bullets--;
        }
    }
}

Split in Multiple Scripts

With OOP we can split the ‘SingleCharacterScript.js’ into Multiple Script:
– Inventory.js -> public class Inventory + subclass Stuff
– MovementControls.js -> variables and functions
– Shooting.js -> variables and functions

Look at Inventory.js

– main class ‘public class Inventory’
– sub class ‘public class Stuff’ nested inside ‘public class Inventory’
– variables ‘public var bullets : int; etc…’
– constructor ‘public function Stuff ()’ it needs the same name of the class ‘Stuff’, to assign default values to variables of a class

You can construct an object in this way:

public function Stuff () // assegno valori senza variare la tipologia di variabile
        {
            bullets = 1;
            grenades = 1;
            rockets = 1;
        }

Or in this way:

public function Stuff(bul : int, gre : int, roc : int) // specifico di che tipo di variabile si tratta
        {
            bullets = bul;
            grenades = gre;
            rockets = roc;
        }

Creare un’istanza delle variabili, praticamente un nuovo oggetto che si basa su uno già esistente.
Notare che ‘Stuff= new Stuff’ dove ‘Stuff’ è lo stesso nome della classe

public var myStuff : Stuff= new Stuff(50, 5, 5);

In caso di costruttori multipli:

public var myStuff : Stuff= new Stuff(50, 5, 5);
USERA’
public function Stuff(bul : int, gre : int, roc : int)
PERCHE’ I PARAMETRI CORRISPONDONO (notare int – int – float)

INVECE

public var myOtherStuff : Stuff= new Stuff(50, 1.5f);
USERA’
public function Stuff(bul : int, fu : float)
PERCHE’ I PARAMETRI CORRISPONDONO (notare int – float)

Attach the Multiple Script at the SAME OBJECT

Inventory.js

#pragma strict

public class Inventory extends MonoBehaviour
{
    public class Stuff // this is a subclass nested inside class Inventory
    {
        public var bullets : int;
        public var grenades : int;
        public var rockets : int;
        public var fuel : float;
        
        public function Stuff(bul : int, gre : int, roc : int)
        {
            bullets = bul;
            grenades = gre;
            rockets = roc;
        }
        
        public function Stuff(bul : int, fu : float)
        {
            bullets = bul;
            fuel = fu;
        }
        
        // Constructor
        public function Stuff ()
        {
            bullets = 1;
            grenades = 1;
            rockets = 1;
        }
    }
    
    
    // Creating an Instance (an Object) of the Stuff class
    public var myStuff : Stuff= new Stuff(50, 5, 5);
    
    public var myOtherStuff : Stuff= new Stuff(50, 1.5f);
    
    function Start ()
    {
        Debug.Log(myStuff.bullets); 
    }
}

MovementControls.js

#pragma strict

public var speed : float;
public var turnSpeed : float;


function Update ()
{
    Movement();
}


function Movement ()
{
    var forwardMovement : float = Input.GetAxis("Vertical") * speed * Time.deltaTime;
    var turnMovement : float = Input.GetAxis("Horizontal") * turnSpeed * Time.deltaTime;
    
    transform.Translate(Vector3.forward * forwardMovement);
    transform.Rotate(Vector3.up * turnMovement);
}

Shooting.js

#pragma strict

public var bulletPrefab : Rigidbody;
public var firePosition : Transform;
public var bulletSpeed : float;


private var inventory : Inventory;


function Awake ()
{
    inventory = GetComponent(Inventory);
}


function Update ()
{
    Shoot();
}


function Shoot ()
{
    if(Input.GetButtonDown("Fire1") && inventory.myStuff.bullets > 0)
    {
        var bulletInstance : Rigidbody = Instantiate(bulletPrefab, firePosition.position, firePosition.rotation);
        bulletInstance.AddForce(firePosition.forward * bulletSpeed);
        inventory.myStuff.bullets--;
    }
}