Unityでのコルーチンの役割と使用法

コルーチン、つまりコルーチンは、戻り値がIEnumeratorである関数と見なすことができますが、StartCoroutineで使用する必要があります。

コルーチンはマルチスレッドではなく、すべてのタスクは引き続きメインスレッドで完了します。これは、非同期マルチタスクの方法です。

コルーチンの利点は、更新のようにフレームごとに特定の部分を実行したり、数秒後に特定の部分を実行したりする関数に実装できることです。

たとえば、タイマーを実装するに
ここに画像の説明を挿入
は、一般的な実装方法は次のとおりです。
ここに画像の説明を挿入
この方法には2つの欠点があり、フレームごとに1回判断して実行する必要があるため、リソースが無駄になります。
多くの変数を作成し、実際には1つの数値のみを変更します。

コルーチンとは対照的
ここに画像の説明を挿入
です。yieldreturnnewWaitForSecondsが1秒後に再度呼び出され、残りが実行されます。

コルーチンを終了するには、stopCoroutineとstopAllCoroutineの2つの関数があります。

ここに画像の説明を挿入

yield return nullは、次のフレームの残りを実行し続けることと同じです。

公式チュートリアルの例を紹介しましょう:

public class CoroutinesExample : MonoBehaviour
{
    
    
    public float smoothing = 1f;
    public Transform target;


    void Start ()
    {
    
    
        StartCoroutine(MyCoroutine(target));
    }


    IEnumerator MyCoroutine (Transform target)
    {
    
    
        while(Vector3.Distance(transform.position, target.position) > 0.05f)
        {
    
    
            transform.position = Vector3.Lerp(transform.position, target.position, smoothing * Time.deltaTime);

            yield return null;
        }

        print("Reached the target.");

        yield return new WaitForSeconds(3f);

        print("MyCoroutine is now finished.");
    }

コルーチンの実行が開始された後、ループ内で毎回nullを返した後、ループ内の操作を実行し続け、ループが終了するまで、ループが終了した後、print "Reachedthetarget"を実行します。 、次にyield return new WaitForSeconds(3f);を実行し、3秒後までこの関数に戻り、print( "MyCoroutine is nowfinished。");を実行します。

コルーチンを使用して例を解析して実装しましょう。
たとえば、画面上の特定の位置をクリックすると、オブジェクトはその位置に移動します。

public class PropertiesAndCoroutines : MonoBehaviour
{
    
    
    public float smoothing = 7f;
    public Vector3 Target
    {
    
    
        get {
    
     return target; }
        set//当target被设置的时候将会执行这部分函数
        {
    
    
            target = value;

            StopCoroutine("Movement");
            StartCoroutine("Movement", target);
        }
    }


    private Vector3 target;


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

            yield return null;
        }
    }

コルーチンメソッドを使用すると、オブジェクトが更新のすべてのフレームをポーリングする必要がないことを認識できます。これにより、効率が向上します。

クリックして関数の位置を設定します:
ClickSetPosition

public class ClickSetPosition : MonoBehaviour
{
    
    
    public PropertiesAndCoroutines coroutineScript;


    void OnMouseDown ()
    {
    
    
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        RaycastHit hit;

        Physics.Raycast(ray, out hit);

        if(hit.collider.gameObject == gameObject)
        {
    
    
            Vector3 newTarget = hit.point + new Vector3(0, 0.5f, 0);
            coroutineScript.Target = newTarget;
        }
    }
}

ScreenPointToRayの関数を追加します。

Camera.ScreenPointToRay
説明
カメラからスクリーンポイントを通過する光線を返します。

結果として生じる光線は、カメラの近平面から始まり、画面上の位置の(x、y)ピクセル座標を通過するワールドスペースにあります(position.zは無視されます)。

画面スペースはピクセルで定義されます。画面の左下隅は(0,0)で、右上隅は(pixelWidth -1、pixelHeight -1)です。

	Camera cam;

    void Start()
    {
    
    
        cam = GetComponent<Camera>();
    }

    void Update()
    {
    
    
        Ray ray = cam.ScreenPointToRay(new Vector3(200, 200, 0));
        Debug.DrawRay(ray.origin, ray.direction * 10, Color.yellow);
    }

Physics.Raycastの機能は、光線を放出することです。たとえば、放出の開始点、距離、方向を指定してから光線を送信できます。
衝突関連の情報を取得する場合は、rayCastHit変数を宣言できます。 、衝突関連の情報を格納するために使用されます。情報の:

        RaycastHit hit;

ここに画像の説明を挿入
次のステートメントを使用して、必要な多くの情報を取得し、光線情報を光線情報変数に出力できます。

      RaycastHit hit;
      Physics.Raycast(ray, out hit);

おすすめ

転載: blog.csdn.net/weixin_43757333/article/details/122843234