В Unity есть набор корутин, позволяющих облегчить разработку последовательно изменяющихся/выполняющихся действий. Большинство из них я опишу ниже.

А для начала давайте взглянем на код:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
using UnityEngine;
using System.Collections;

public class CorutineTutor : MonoBehaviour
{
    public Texture2D texture;

    private Vector3 _position;

    public void Start()
    {
        // запускаем корутину
        StartCoroutine(Coroutine());
    }

    public IEnumerator Coroutine()
    {
        // центр экрана
        Vector3 centerScreen = new Vector3(Screen.width/2f, Screen.height/2f, 0);

        // бесконечный цикл
        while (true)
        {
            float time = Time.realtimeSinceStartup;

            // перемещение по "кренделю" :)
            _position = centerScreen +
                new Vector3(200 * Mathf.Sin(time), 200 * Mathf.Cos(time), 0) * Mathf.Sin(time / 3);

            // остановка выполнения функции на 10 миллисекунд
            yield return new WaitForSeconds(0.01f);
        }
    }


    public void OnGUI()
    {
        // рисуем текстуру
        GUI.DrawTexture(
            new Rect(
                _position.x - texture.width / 2f,
                _position.y - texture.height / 2f,
                texture.width,
                texture.height
                ), texture);
    }
}

демо работы скрипта

Суть работы кода такова: текстура на экране двигается по фигуре “крендель” с равной скоростью. Ничего особенного, и я даже пример выбрал не особо показательный, но все же продолжу.

Корутина позволяет прерывать вычисления функции и продолжать с того же места, на котором остановились. В моем примере есть функция Coroutine, которая имеет бесконечный цикл, из которого нет выхода. Каждая итерация цикла считает новое положение текстуры на экране и останавливается на 10 мс, перед тем как продолжить. Но загадка в том, что прерывание этой функции происходит не с помощью остановки процесса, а с помощью механизма корутин юнити.

Итак последовательно:
1. При старте скрипта запускается корутина (функция с названием Coroutine).
2. Эта функция выполняется до строчки yield return new WaitForSeconds(0.01f); которая прерывает ее работу на 10 миллисекунд.
3. Прерывание не влияет на остальные функции (процесс не останавливается и действие происходит в том же потоке)
4. По истечении времени корутина продолжает бесконечный цикл пока снова не доходит до строки с задержкой.
5. Функция OnGUI рисует текстуру на экране.

Возможные прерывания выполнения кода:
1. yield return null; – прерывает выполнение корутины до следующего кадра.
2. yield break; завершает выполнение корутины.
3. yield return new WaitForSeconds( количество секунд ); – прерывает на время.
4. yield return new WaitForEndOfFrame(); – прерывает выполнение до конца кадра.
5. yield return new WaitForFixedUpdate(); – прерывает выполнение до кадра, в котором обновляется физика.

Специфическое использование:

1
2
3
4
5
6
7
8
9
10
11
12
13
// Скриншот  "Friday's" in Times Square
string url = "http://images.earthcam.com/ec_metros/ourcams/fridays.jpg";
public IEnumerator Start ()
{
     // Запуск скачивания картинки по приведенной url
    WWW www  = new WWW (url);
   
    // ожидание конца скачивания
    yield return www;
   
    // применение загруженной текстуры к материалу
    renderer.material.mainTexture = www.texture;
}

Чтобы использовать корутины в C# необходимо объявлять эти функции с типом IEnumerator. Для JavaScript этого не нужно.

Еще один пример как можно реализовать то же самое, что и выше в функции Coroutine но без бесконечного цикла:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
    public IEnumerator Coroutine()
    {
        // центр экрана
        Vector3 centerScreen = new Vector3(Screen.width/2f, Screen.height/2f, 0);

        float time = Time.realtimeSinceStartup;

        // перемещение по "кренделю" :)
        _position = centerScreen +
                new Vector3(200 * Mathf.Sin(time), 200 * Mathf.Cos(time), 0) * Mathf.Sin(time / 3);

        // остановка выполнения функции на 10 миллисекунд
        yield return new WaitForSeconds(0.01f);

         // запускаем корутину снова
        StartCoroutine(Coroutine());
    }

Ну вот и все на сегодня :) .

VN:F [1.9.3_1094]
Rating: 9.2/10 (21 votes cast)
VN:F [1.9.3_1094]
Rating: +7 (from 7 votes)
Сопрограммы (Coroutine) в Unity, 9.2 out of 10 based on 21 ratings

2 комментария на «Сопрограммы (Coroutine) в Unity»

  1. Armando

    lewisohn@dora.progandist” rel=”nofollow”>.…

    спс….

    VA:F [1.9.3_1094]
    Rating: 0.0/5 (0 votes cast)
    VA:F [1.9.3_1094]
    Rating: 0 (from 0 votes)
  2. Clarence

    palindromes@abdominis.gainful” rel=”nofollow”>.…

    благодарен!!…

    VA:F [1.9.3_1094]
    Rating: 0.0/5 (0 votes cast)
    VA:F [1.9.3_1094]
    Rating: 0 (from 0 votes)

Ваш отзыв

Вы должны войти, чтобы оставлять комментарии.



Страница 1 of 0