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/