Unityに関連する記事です

注意点


 1.IEnumerator 型の変数を作成してコルーチンとして実行する。
 2.yield retrun で実行しているコルーチン処理でなければ取得できない。
 3.コルーチンメソッド内部で yield return の処理を書き、戻り値の値を用意する

 非同期処理のため、処理が終了するタイミングまで待たないと処理結果は取得出来ません。
また、IEnumerator 型の変数内部にアクセスすることで yield return で用意されている戻り値が取得できるため、
変数に代入して実行しないと取得出来ません。


コルーチンから戻り値を取得する


 コルーチンから戻り値を取得するには、コルーチン内でyield return文を使用し、その後の処理をコルーチンが完了した後に実行する必要があります。
具体的な手順は以下の通りです。

 1.IEnumerator型の変数を宣言し、yield return 付きの StartCoroutine の引数として実行します。
 2.コルーチンメソッド内でyield returnを使って値を返します。
 3.コルーチンが完了した後、その IEnumerator型の変数から値を取得します。

 以下にサンプルコードを示します。


private IEnumerator Start()
{
  // IEnumerator 型の coroutine 変数を宣言し、実行したいコルーチンメソッドを代入する
  IEnumerator coroutine = MyCoroutine();

  // Start メソッドをコルーチンメソッドに変更しているので、 Ν△里匹舛蕕諒法でも実行可能
  // コルーチンメソッドを実行
    yield return StartCoroutine(coroutine);

  // コルーチンメソッドを実行
    yield return coroutine;

  // コルーチンメソッド内から戻り値を Current として取得する
  int result = (int)coroutine.Current;

    Debug.Log("コルーチンからの戻り値: " + result);
}

private IEnumerator MyCoroutine()
{
    yield return new WaitForSeconds(2f); // 2秒待つ
    yield return 42; // 42を返す
}

 コルーチンメソッドの代入されている変数に対して、Current プロパティを実行することで
yield return されている値を戻り値として取得出来ます。

 これは object 型になるため、明示的な変換(キャスト)処理が必要になります。



 通常の Start メソッドでは正常に動作しません。

private IEnumerator Start()
{
  // IEnumerator 型の coroutine 変数を宣言し、実行したいコルーチンメソッドを代入する
  IEnumerator coroutine = MyCoroutine();

  // コルーチンメソッドを実行
    StartCoroutine(coroutine);

  int result = (int)coroutine.Current;

    Debug.Log("コルーチンからの戻り値: " + result);
}

 このような形で書くことになるため、コルーチンメソッドの処理結果を待たずに下の処理が実行されます。
そのため、コルーチンメソッド内の戻り値は取得出来ません。(null になります)


参考サイト
ハルシオンシステム 様
【ハルシオンブログ】Unityのコルーチンで値を返す方法。いくつか方法あるぽいけど、その一つを紹介。


コルーチンから戻り値を取得する


 コルーチンメソッドに Action 型で、事前に戻り値を受け取るために用意した変数を引数を渡して実行する方法です。


using System;
using System.Collections;
using UnityEngine;

public class CoroutineReturnValue : MonoBehaviour
{
    private IEnumerator Start()
    {
        int value = 0;
        yield return StartCoroutine(MyCoroutine(x => value = x));
        Debug.Log("コルーチンからの戻り値の結果: " + value);
    }

    private IEnumerator MyCoroutine(Action<int> callback)
    {
        yield return new WaitForSeconds(2f); // 2秒待つ
        int result = 42; // 42を返す
        callback(result); // 戻り値をコールバックで外部に通知
    }
}



 コルーチンメソッド内の callback(result) の部分については、null チェックを行った方がよいでしょう。
以下の2つの方法をサンプルとして提示します。


< if 文を使用する方法>
    private IEnumerator MyCoroutine(Action<int> callback)
    {
        yield return new WaitForSeconds(2f); // 2秒待つ
        int result = 42; // 42を返す

        if (callback != null)
        {
             callback(result); // 戻り値をコールバックで外部に通知
        }
    }



<◆?.演算子を使用する方法>
    private IEnumerator MyCoroutine(Action<int> callback)
    {
        yield return new WaitForSeconds(2f); // 2秒待つ
        int result = 42; // 42を返す

        callback?.Invoke(result);// 戻り値をコールバックで外部に通知
    }

 null チェックすることで安全に実行できます。

森ちゃんのUnity開発録
【Unity】非同期処理、IEnumeratorで返り値(戻り値)を実装する


UniTask の場合


 コルーチンメソッドから戻り値を取得するには手間がかかりますので、UniTask による非同期処理を活用しましょう。

 プロジェクトにUniTaskの依存関係を追加し、UniTaskを使用できるようにすることを忘れないでください。

using System;
using Cysharp.Threading.Tasks;
using UnityEngine;

public class UniTaskExample : MonoBehaviour
{
    private async void Start()
    {
        int result = await MyUniTask();
        Debug.Log("UniTaskからの戻り値: " + result);
    }

    private async UniTask<int> MyUniTask()
    {
        await UniTask.Delay(TimeSpan.FromSeconds(2)); // 2秒待つ
        return 42;
    }
}

 この例では、UniTaskのUniTask.Delayメソッドを使用して非同期処理を行い、awaitキーワードを使用して非同期操作が完了するのを待っています。
その後、UniTaskからの戻り値を取得しています。

 UniTask の戻り値は T(ジェネリック)型ですので、任意の型を指定できます。また、戻り値なしでも設定できます。


UniTaskの利点


 UniTask による非同期処理は、待機前提で実装可能な書式になっています。
コルーチンによる非同期処理は、待機しない前提での書式です。
待機させるにはコルーチンメソッド内部で、yield return をつける必要があります。

 この部分に大きな違いがありますので、UniTask は戻り値を受け取ることが前提の設計になっています。

 UniTaskは、非同期メソッドから複数の値を戻すためにタプルやカスタムクラスなどの方法を提供します。
これにより、複数の異なるデータを一度に取得でき、コードをより効率的に記述できます。
この利点は、複雑な非同期操作やデータの並行処理が必要な場合に特に役立ちます。

 以下に、複数の値を戻すUniTaskのサンプルコードを示します。

using System;
using Cysharp.Threading.Tasks;
using UnityEngine;

public class UniTaskMultipleValuesExample : MonoBehaviour
{
    private async void Start()
    {
        (int, string) result = await MyUniTaskWithMultipleValues();
        Debug.Log("UniTaskからの戻り値: " + result.Item1 + ", " + result.Item2);
    }

    private async UniTask<(int, string)> MyUniTaskWithMultipleValues()
    {
        await UniTask.Delay(TimeSpan.FromSeconds(2)); // 2秒待つ
        return (42, "Hello, World!");
    }
}

 この例では、MyUniTaskWithMultipleValuesメソッドがUniTaskを使用して2つの異なる値(整数と文字列)を返します。
コード内でタプル (int, string) を使用してこれらの値を取得し、それぞれ result.Item1 と result.Item2 でアクセスしています。

 UniTaskを使用することで、非同期処理から複数の戻り値を取得することができ、コードをより簡潔かつ効率的に記述できるようになります。

コメントをかく


「http://」を含む投稿は禁止されています。

利用規約をご確認のうえご記入下さい

Menu



技術/知識(実装例)

2Dおはじきゲーム(発展編)

2D強制横スクロールアクション(発展編)

3Dダイビングアクション(発展編)

2Dタップシューティング(拡張編)

レースゲーム(抜粋)

2D放置ゲーム(発展編)

3Dレールガンシューティング(応用編)

3D脱出ゲーム(抜粋)

2Dリアルタイムストラテジー

2Dトップビューアドベンチャー(宴アセット使用)

3Dタップアクション(NavMeshAgent 使用)

2Dトップビューアクション(カエルの為に〜、ボコスカウォーズ風)

VideoPlayer イベント連動の実装例

VideoPlayer リスト内からムービー再生の実装例(発展)

AR 画像付きオブジェクト生成の実装例

AR リスト内から生成の実装例(発展)

private



このサイト内の作品はユニティちゃんライセンス条項の元に提供されています。

管理人/副管理人のみ編集できます