Unity 3D Game Engine – Quaternions

Unity 3D Game Engine – Quaternions

In mathematics, the quaternions are a number system that extends the complex numbers. They were first described by Irish mathematician William Rowan Hamilton in 1843 and applied to mechanics in three-dimensional space.

According to Euler’s rotation theorem, any rotation or sequence of rotations of a rigid body or coordinate system about a fixed point is equivalent to a single rotation by a given angle θ about a fixed axis (called Euler axis) that runs through the fixed point. The Euler axis is typically represented by a unit vector u→. Therefore, any rotation in three dimensions can be represented as a combination of a vector u→ and a scalar θ. Quaternions give a simple way to encode this axis–angle representation in four numbers, and to apply the corresponding rotation to a position vector representing a point relative to the origin in R3.

Unity utilizes the quaternion system to manage the rotation of game objects.

In Unity Quaternions have 4 componments: X Y Z W and they work together to define any rotations.

Look At

Inside Hierarchy create:

1. Sphere and attach MotionScript.js


#pragma strict

public var speed : float = 3f;


function Update () 
{
    transform.Translate(-Input.GetAxis("Horizontal") * speed * Time.deltaTime, 0, 0);
}

2. Cube and attach LookAtScript.js


#pragma strict

public var target : Transform;

function Update () 
{
    var relativePos : Vector3 = target.position - transform.position;
    transform.rotation = Quaternion.LookRotation(relativePos);
}

Inspector> LookAtScript.js> DRAG AND DROP Sphere over var target

3. Play> Move the Sphere using keyboard arrow, the Cube will look at the Sphere

Gravity – Orbit

Inside Hierarchy create:

1. Sphere

2. Cube and attach GravityScript.js


#pragma strict

public var target : Transform;
    
    
function Update () 
{
    var relativePos : Vector3 = (target.position + new Vector3(0, 1.5f, 0)) - transform.position;
    var rotation : Quaternion = Quaternion.LookRotation(relativePos);
    
    var current : Quaternion = transform.localRotation;
    
    // Spherical Linear Interpolation
    transform.localRotation = Quaternion.Slerp(current, rotation, Time.deltaTime);
    transform.Translate(0, 0, 3 * Time.deltaTime);
}
 

Inspector> GravityScript.js> DRAG AND DROP Sphere over var target

3. Play> the Cube will rotate around the Sphere as a planet around the sun.

By |Unity3D, Video Games Development|Commenti disabilitati su Unity 3D Game Engine – Quaternions

Unity 3D Game Engine – JavaScript – Coroutines

Unity 3D Game Engine – JavaScript – Coroutines

Coroutines permettono di gestire comportamenti complessi tra classi differenti.
Coroutines possono essere pensate come funzioni da eseguire a intervalli.
Le Coroutine vanno pecificate con Maiuscolanome+Coroutine, ad esempio MyCoroutine StopCoroutine etc…

Basic

1. Creo un Cube

2. Creo una Sphere ed assegno Coroutine.js

Coroutine.js:


#pragma strict

public var smoothing : float = 1f;
public var target : Transform; // Inspector DRAG over here another GameObject
    
function Start () 
{
    MyCoroutine(target);
}

function MyCoroutine (target : Transform)
{
    while(Vector3.Distance(transform.position, target.position) > 0.05f)
    {
        transform.position = Vector3.Lerp(transform.position, target.position, smoothing * Time.deltaTime);
        
        yield;
    }
    
    print("Reached the target.");
    
    yield WaitForSeconds(3f);
    
    print("MyCoroutine is now finished.");
}

3. Sphere> Inspector> Couroutine.js> DRAG AND DROP Cube GameObject over var target

4. Play: Sphere raggiungerà si muoverà con interpolazione lineare (Lerp) il Cubo-> print(“Reached the target.”)-> dopo 3 sec-> print(“MyCoroutine is now finished.”);

Come funziona?

1. Start() si avvia al caricamento dello script
2. Start() invia alla funzione MyCoroutine() il valore della variabile target, che è la posizione XYZ di Cube

Proprietà

Assegno a Sphere:

PropertiesAndCoroutines.js


#pragma strict

public var smoothing : float = 7f;
private var target : Vector3;

function  SetTarget(value : Vector3)
{
    target = value;
        
    StopCoroutine("Movement");
    StartCoroutine("Movement", target);
}

function Movement (target : Vector3)
{
    while(Vector3.Distance(transform.position, target) > 0.05f)
    {
        transform.position = Vector3.Lerp(transform.position, target, smoothing * Time.deltaTime);
        
        yield;
    }
}

Assegno al piano dove si muoverà Sphere

ClickSetPosition.js


#pragma strict

public var coroutineScript : PropertiesAndCoroutines; // richiama lo script sopra
    

function OnMouseDown ()
{
    var ray : Ray = Camera.main.ScreenPointToRay(Input.mousePosition);
    var hit : RaycastHit;
    
    Physics.Raycast(ray, hit);
    
    if(hit.collider.gameObject == gameObject)
    {
        var newTarget : Vector3 = hit.point;
        // invia il parametro target allo script PropertiesAndCoroutines        
        coroutineScript.SetTarget(newTarget); 
    }
}

Come funziona?

1. ClickSetPosition.js
– al click il RayCast, calcolato da Camera.main definisce un valore Vector3 XYZ di posizione
– il valore viene mandato alla Coroutine con coroutineScript.SetTarget(newTarget)

2. PropertiesAndCoroutines.js
– riceve il valore XYZ
– ferma la Couroutine, se l’oggetto si sta muovendo viene arrestato
– avvia di nuovo la Courotine, l’oggetto si sposterà verso la nuova destinazione.

Other Examples

Ex 1

function MyCoroutine()
{
    DoSomething():
    yield;                  // wait one frame                        
    DoSomethingElse();
}

Ex 2

function MyCoroutine()
{
    DoSomething():          //Do this immediately
    yield;                  //Return control to the caller
    DoSomethingElse();      //This will be executed one frame later
}
 
void Start()
{
    MyCoroutine();
}

Ex 3

function MyCoroutine()
{
    print("This is printed second");
    yield;                 //Return control to the Start function
    print("This is printed one fourth, exactly one frame after the third");
}
 
void Start()
{
    print("This is printed first");
    MyCoroutine();
    print("This is printed third");
}

Ex 4

function MyCoroutine()
{
    DoSomething():              //Do this immediately
    yield WaitForSeconds(2);    //Return control to the caller
    DoSomethingElse();          //This will be executed 2 seconds after
}
 
void Start()
{
    MyCoroutine();
}

Ex 5

function MyCoroutine()
{
    DoSomething():              //Do this immediately
    yield MyOtherCoroutine();   //Go and execute MyOtherCoroutine!
    DoSomethingElse();          //This will be executed after MyOtherCoroutine finished execution
}
 
function MyOtherCoroutine()
{
    DoStuff():                  //Do this immediately
    yield WaitForSeconds(2);    //Return control to the caller (in this case the Start function)
    DoMoreStuff();              //This will be executed 2 seconds after
    //MyOtherCoroutine finishes execution here
}
 
void Start()
{
    MyCoroutine();
}

References:
– unity3d.com/
– http://www.blog.silentkraken.com/2010/01/22/coroutines-in-unity3d/

By |Unity3D, Video Games Development|Commenti disabilitati su Unity 3D Game Engine – JavaScript – Coroutines

Unity 3D Game Engine – JavaScript – Interfaces

Unity 3D Game Engine – JavaScript – Interfaces

I ‘contratti’ di Interfaces permettono di aggiungere ad una classe nuove funzioni specificate all’interno di un’altra classe esterna.

Se 2 classi sono A padre->B figlio il figlio potrà usare le funzioni del padre
Se 2 classi hanno un contratto di Interface la classe A (interface) è estesa nelle funzioni dalla classe B (B implements A)

Le Interfaces vengono dichiarate con ‘I maiuscola+lettera maiuscola+nome’, ad esempio IKillable, IDamageable etc…

Le interfaces sono utili quando dobbiamo mettere in relazioni classi che non ha senso considerare padre-figlio. Ad esempio una classe Muro e una classe Auto non ha senso che siano padre-figlio, ma in comune potrebbero avere il fatto che entrambe possono essere danneggiate.

Interfaces.


#pragma strict

//This is a basic interface with a single required
//method.
public interface IKillable
{
    function Kill();
}

//Javascript does not allow generic types to
//be defined, so this version of IDamageable
//uses a float type
public interface IDamageable
{
    function Damage(damageTaken : float);
}

Avatar Class


#pragma strict

public class Avatar extends MonoBehaviour implements IKillable, IDamageable
{
    //The required method of the IKillable interface
    public function Kill()
    {
        //Do something fun
    }
    
    //The required method of the IDamageable interface
    public function Damage(damageTaken : float)
    {
        //Do something fun
    }
}

Come funziona?

1. Avatar Class
– classe pubblica Avatar implementa Interface IKillable
– funzione pubblica Kill() e Damage()

2. Interfaces
– public interface IKillable -> richiama la funzione Kill() da Avatar Class

By |Unity3D, Video Games Development|Commenti disabilitati su Unity 3D Game Engine – JavaScript – Interfaces

Unity 3D Game Engine – JavaScript – Overriding

Unity 3D Game Engine – JavaScript – Overriding

Overriding è una pratica che consente di sovrascrivere un metodo della classe padre con un metodo della classe figlia.

Fruit Class


#pragma strict

public class Fruit 
{
    public function Fruit ()
    {
        Debug.Log("1st Fruit Constructor Called");
    }
    
    //Overriding members happens automatically in 
    //Javascript and doesn't require additional keywords
    public function Chop ()
    {
        Debug.Log("The fruit has been chopped.");     
    }
    
    public function SayHello ()
    {
        Debug.Log("Hello, I am a fruit.");
    }
}

Apple Class


#pragma strict

public class Apple extends Fruit 
{
    public function Apple ()
    {
        Debug.Log("1st Apple Constructor Called");
    }
    
    //Overriding members happens automatically in 
    //Javascript and doesn't require additional keywords
    public function Chop ()
    {
        super.Chop();
        Debug.Log("The apple has been chopped.");     
    }
    
    public function SayHello ()
    {
        super.SayHello();
        Debug.Log("Hello, I am an apple.");
    }
}

FruitSalad Class


#pragma strict

function Start () 
{
    var myApple = new Apple();
    
    //Notice that the Apple version of the methods
    //override the fruit versions. Also notice that
    //since the Apple versions call the Fruit version with
    //the "base" keyword, both are called.
    myApple.SayHello();
    myApple.Chop(); 
    
    //Overriding is also useful in a polymorphic situation.
    //Since the methods of the Fruit class are "virtual" and
    //the methods of the Apple class are "override", when we 
    //upcast an Apple into a Fruit, the Apple version of the 
    //Methods are used.
    var myFruit = new Apple();
    myFruit.SayHello();
    myFruit.Chop();
}

Come funziona?

1. Fruit Class
– una classe pubblica Fruit con le funzioni Fruit() – Chop() – SayHello()

2. Apple Class
– classe figlia di Fruit con le funzioni
– Apple()
– Chop()-> super.Chop()
– SayHello()-> super.SayHello()

3. FruitSalad Class
– la funzione Start() si avvia la caricamento dello script
– richiama Apple().SayHello() e Apple().Chop() -> che vanno in ovverride su Fruit().SayHello() e Fruit().Chop()

By |Unity3D, Video Games Development|Commenti disabilitati su Unity 3D Game Engine – JavaScript – Overriding

Unity 3D Game Engine – Java Script – Polymorphism – Upcasting – Downcasting

Unity 3D Game Engine – Java Script – Polymorphism – Upcasting – Downcasting

Polymorphism – Upcasting – Downcasting vengono utilizzate per creare funzioni dinamiche tra classi legate da parentela padre-figlio.

Fruit Class


#pragma strict

public class Fruit 
{
    public function Fruit ()
    {
        Debug.Log("1st Fruit Constructor Called");
    }
    
    public function Chop ()
    {
        Debug.Log("The fruit has been chopped.");     
    }
    
    public function SayHello ()
    {
        Debug.Log("Hello, I am a fruit.");
    }
}

Apple Class


#pragma strict

public class Apple extends Fruit 
{
    public function Apple ()
    {
        Debug.Log("1st Apple Constructor Called");
    }
    
    //Apple has its own version of Chop() and SayHello(). 
    //When running the scripts, notice when Fruit's version
    //of these methods are called and when Apple's version
    //of these methods are called.
    //In this example, the "new" keyword is used to supress
    //warnings from Unity while not overriding the methods
    //in the Apple class.
    public function Chop ()
    {
        Debug.Log("The apple has been chopped.");     
    }
    
    public function SayHello ()
    {
        Debug.Log("Hello, I am an apple.");
    }
}

FruitSalad Class


#pragma strict

function Start () 
{
    //Notice here how the variable "myFruit" is of type
    //Fruit but is being assigned a reference to an Apple. This
    //works because of Polymorphism. Since an Apple is a Fruit,
    //this works just fine. While the Apple reference is stored
    //in a Fruit variable, it can only be used like a Fruit
    var myFruit = new Apple();

    myFruit.SayHello();
    myFruit.Chop();
    
    //This is called downcasting. The variable "myFruit" which is 
    //of type Fruit, actually contains a reference to an Apple. Therefore,
    //it can safely be turned back into an Apple variable. This allows
    //it to be used like an Apple, where before it could only be used
    //like a Fruit.
    var myApple = myFruit as Apple;
    
    myApple.SayHello();
    myApple.Chop(); 
}

Come funziona?

1. Fruit Class
– al suo interno ha i costruttori pubblici Fruit() – Chop() – SayHello()

2. Apple Class
– è una classe figlia di Fruit Class ‘… class Apple extends Fruit …’
– ha il proprio costruttore Chop() – SayHello()

3. FruitSalad Class
– la funzione Start() è la prima che si avvia al caricamento dello script
– richiama Apple().SayHello – Apple().Chop()
– fa il Downcasting a:


var myApple = myFruit as Apple;

quindi sarà richiamata Fruit().SayHello – Fruit().Chop()

Apple appartiene di sicuro alla categoria Fruit, ma non è detto che sia vero il contrario.

By |Unity3D, Video Games Development|Commenti disabilitati su Unity 3D Game Engine – Java Script – Polymorphism – Upcasting – Downcasting