Unityコルーチンの深い理解

コルーチンは多くのプログラミング言語でサポートされており、たとえば、前述のLuaでは、コルーチンは仮想スレッド化テクノロジーです。


簡単な説明


コンピューターを購入するときに通常言及することを考えてください。CPUは4コアと8スレッドです。実際、CPUは1つの処理しか処理できません。つまり、CPUはデフォルトで1スレッドに対応する1コアに設定されます。タスク、そして私たちはそれほど多くのスレッドを持っていません。
次に、仮想スレッドの概念を提唱し、CPUの単一スレッドを仮想化し、複数のスレッドを作成します。これにより、4つのコアと8つのスレッド、8つのコアと16のスレッドの概念が得られます。アプリケーション側にもスレッドがあります。そして、プロセスの概念は、プロセスを細分化した後、仮想化ソフトウェアのスレッドにコルーチンの概念があります。

これで、コルーチンはスレッドのサブディビジョンであり、スレッドの再仮想化であることがわかりました。

 Unityコルーチン


コルーチンの概念は新しいものではありませんが、「コルーチン」という用語が現在のインターネット開発分野に関与することはほとんどありません。
コルーチンは、1つのことを達成するために一緒に作業することです。マルチスレッドの概念を考えるのは簡単です。たとえば、ネットワークリクエストを行うとき、次の操作の前に応答を待つ必要があります。このとき、 `ミューテックス`と `スレッドを使用します。セキュリティ `などのコンセプト。
Unityまたはゲームエンジンでは、ゲームのメインループスレッドの制約により、マルチスレッドの安全性を確保することは不可能です。現時点では、コルーチンを引き続き使用して、同じスレッドでマルチスレッドの作業を継続することが特に重要です。
(Unityもパフォーマンス優先のECSモードから撤退し、Monoフレームワークを放棄し、マルチスレッド開発で支援できる開発モ​​ードを実装しました。)
次に、主にUnity コルーチンを詳細に紹介します。

 Unityコルーチンの例


この例を見てください:

//创建协程
private IEnumerator Cor1()
{
    yield return new WaitForSeconds(2f);
    Debug.Log("2s到了");
}
//启动协程
StartCoroutine(Cor1());


これは簡単な例です。コルーチンは、もともとCsharpの反復子パターンの実装であった `IEnumerator`反復可能オブジェクトを返す必要があり、UnityはコルーチンをUnityのプロトタイプとして実装していることがわかります。

 コルーチンのパラメーター


上記では、 `new WaitForSeconds()`を使用しました。これは、指定された時間待機することを意味します。[WaitForSecondsはTime.Scaleに関連していることに注意してください]
上記で使用したWaitForSeconds以外にも多くのパラメーターがあります。これらのパラメーターは時間がかかるか、ブール値を返します。要するに、moveNextを決定する必要があります。


コルーチンの使用

 

1.持続時間が不確実な状況で使用されます(例:ネットワーク要求、ファイルの読み取りと書き込み)
2.遅延実行用
3.単純なタイマーとして使用できます(例:敵のバッチの生成)

 コルーチンのネスト


コルーチンはネストをサポートしています以下は、コルーチンを使用したパトロールの簡単な実装です。
**注:1の場合、コルーチンは0またはnullを返し、次のフレームを待ちます。**

using System;
using System.Collections;
using UnityEngine;

namespace Coroutines
{
    //协程测试
    public class CoroutTest : MonoBehaviour
    {
        public Transform[] wayPoints;

        private bool isLoop;

        private void Start()
        {
            isLoop = true;
            StartCoroutine(StartLoop());
        }

        private IEnumerator StartLoop()
        {
            do
            {
                foreach (var point in wayPoints)
                {
                    yield return StartCoroutine(MoveTarget(point.position));
                }
            } while (isLoop);
        }

        private IEnumerator MoveTarget(Vector3 target)
        {
            while (transform.position!=target)
            {
                transform.position = Vector3.MoveTowards(transform.position, target, 3 * Time.deltaTime);
                yield return 0;
            }
        }
    }
}


 コルーチンを動かす

 

+ StartCoroutine(nameof(StartLoop));
コルーチンを文字列の形式で開始し、外部でコルーチンを停止でき、パラメータを渡すことはできません。

+ StartCoroutine(StartLoop);
イテレータの形式でコルーチンを開始し、パラメーターを渡すことができ、外部でstopを使用してコルーチンを停止することはできません。

###コルーチンを停止させる
コルーチンは基本的にイテレータで、moveNextがfalseの場合、コルーチン内のすべてのアイテムが実行されています。
Unityでコルーチンを停止するには、いくつかの方法があります。

1. StopCoroutine()このメソッドは、文字列の形式で開始されたコルーチンのみを停止できることに注意してください[コルーチンの外側で使用]
2. コルーチンのブレークアウトを生成[コルーチンの内側で
使用] 3.ロジックを使用して停止[ コルーチンの作成] プロセスの実行条件が満たされていません]
4.オブジェクトを非アクティブに設定します[コルーチンを再度アクティブにしても復元されません]
5. StopAllCoroutine()すべてのコルーチンを終了します

上記のコルーチンのネストの例のように、コルーチンを停止したい場合は、次のようにし
ます。1. isLoop = falseに設定し、一度実行した後で条件を満たさない場合は自動的に停止します
2.コルーチン内でブレークします
 

if (transform.position==wayPoints[2].position)
{
    yield break;
}


3.コルーチンの外側で停止します
 

 StopCoroutine(nameof(StartLoop));

 コルーチンのデザインアイデア

 コルーチンは更新を置き換えますか?


上記の例から、コルーチンは実際には更新の別の実装であることがわかります。プログラムを完了するために、更新とfixedUpdateなしでコルーチンのみを使用することもできます。
しかし、これを行うと、そうではありませんか?コルーチンは、ユニティによって導入される遅延実行のパラダイムであり、更新の上位層に基づいています。

コルーチンを使用すると、プログラムの効率が大幅に向上しますか?


いいえ、コルーチンは基本的に1つのスレッド上にあります。複数のコルーチンを並列化できますが、これらのコルーチンは常に1つのスレッド上で実行されるため、速度と効率は大幅には向上しません。代わりに、複数のスレッドが並行して開かれ、スレッドは多くのコルーチンの状態を監視する必要があります。多数のコルーチンが終了すると、多数のGCがトリガーされ、プログラムの効率が低下する可能性があります。

 まとめ


コルーチンはスレッド上で実行されるスレッドであり、その動作モードは依然として単一スレッドに基づいており、コルーチンを使用しているためプログラムの操作効率は向上しませんが、コルーチンを記述する便利な方法と強力な関数は開発者として私たちを向上させることができます開発効率。
ある意味で、コルーチンはより美しい構文糖のようなものです

25件の元の記事を公開 Likes6 10,000以上の訪問数

おすすめ

転載: blog.csdn.net/qq_37446649/article/details/105647645