ايقاف عمل ال method حتى … (yield instruction)

بامكانك ايقاف عمل method حتى يتحقق شرط ما وهذا ما يعرف في unity باسم coroutine . الفكرة قائمة على استخدام yield return لايقاف العمل على ال method مؤقتا او yield break لانهاء عمل ال method وهي فكرة متأصلة في c# ولكن unity طورتها لتؤدي الغرض المطلوب منها .

مثال بسيط يشرح الفكرة لنفترض انه لديك ال method التالي

public IEnumerator coroutine()
{
     int i = 0;
     while(true)
     {
         i++;
         if(i>100) yield break;
         yield return null;
         print("coroutine : " + i);
     }
}

فانه بامكانك عمل loop واحد في كل update بطريقتين اما

IEnumerator enumerator;
int i;
	// Use this for initialization
void Start () {
        i=0;
        enumerator=coroutine();
}
	
	// Update is called once per frame
void Update () {
        this.i++;
        print("update : " + this.i);
        enumerator.MoveNext();
}

او

void Start () {
        this.StartCoroutine(coroutine());
}

وكلاهما يعيدان نفس النتيجة

update : 1
update : 2
coroutine : 1
update : 3
coroutine : 2
update : 4
coroutine : 3
update : 5
coroutine : 4
.
.
.
update : 101
coroutine : 100
update : 102
update : 103
update : 104
.
.
.

هذا مثال بسيط لكن قد تتعقد الامور اكثر في حال كان yield return تعيد enumerator اخر وانت تريد انهاء ال enumerator الجديد ثم الرجوع للقديم وانهاءه , وهذا مايفعلها ال startCoroutine حيث في حال وجد enumarator جديد داخل القديم فانه ينهيه ثم يرجع للقديم  .

مثال

public IEnumerator coroutine()
{
    int i = 0;
    while(true)
    {
        i++;
        if(i>100) yield break;
        yield return null;
        print("coroutine : " + i);
    }
}

public IEnumerator coroutine2()
{
    yield return coroutine();// return new enumerator
    print("the end");
}
void Start () {
        this.StartCoroutine(coroutine());
}

سوف يكون الناتج مشابه للسابق ولكن في نهاية تنفيذ coroutine سوف ينهي عمله في coroutine2

update : 1
update : 2
coroutine : 1
update : 3
coroutine : 2
update : 4
coroutine : 3
update : 5
coroutine : 4
.
.
.
update : 101
coroutine : 100
the end
update : 102
update : 103
update : 104
.
.
.

وايضا هناك طريقة أخرى لارجاع نفس الناتج

public IEnumerator coroutine2()
{
      yield return this.StartCoroutine(coroutine());
      print("the end");
}

StartCoroutine ترجع coroutine التي تعتبر yield instruction فلذلك تعمل نفس عمل الكود السابق
هناك بعض ال yields instructions المعرفة مسبقا ويتم استدعاءها في اماكن مختلفة مثل WaitForFixedUpdate فانه يتم استدعاءها في نهاية كل fixed update
اليك مخطط لاهم yield instructions واماكن توزيع عملهم

امثلة

public IEnumerator coroutine()
{
        yield return new WaitForFixedUpdate();
        print("after fixed update");
        yield return null;
        print("after update");
        yield return new WaitForEndOfFrame();
        print("after late update");
}

public IEnumerator coroutine2()
{
        int i = 0;
        yield return new WaitWhile(() => { i++; return i < 100; });// wait while delegate return true check after update
        print(i);//100
        yield return new WaitUntil(() => { i--; return i < 1; });// wait while delegate return false check after update
        print(i);//0
}

 



التصنيف : unity
كلمات مفتاحية :