Unityで実装された30秒監視機能のAsync/awaitバージョン解説とリファクタリング資料

この資料では、Unityにおけるオブジェクトの生存時間を監視する仕組みを、従来のコルーチンではなく Async/await を用いて実装した例を紹介します。元のコルーチン実装と同様に、オブジェクトの生存時間を毎秒ログ出力し、30秒を超えた時点で処理を停止します。


1. はじめに

  • 目的:
    ゲームオブジェクトの生存時間を非同期処理(Async/await)で毎秒ログ出力し、30秒経過後に処理を終了する。
  • ポイント:
    • Async/awaitを利用して、従来のコルーチンと同等のタイマー機能を実現する方法
    • 非同期メソッドによるシンプルな実装と保守性の向上

2. Async/awaitバージョンのコード

以下は、Async/awaitを用いて実装した例です。

using System.Threading.Tasks;
using UnityEngine;

public class Check30SecAsync : MonoBehaviour
{
    private float startTime;
    private const float MaxLifetime = 30f;

    private async void Start()
    {
        startTime = Time.realtimeSinceStartup;
        await TrackLifetimeAsync();
    }

    private async Task TrackLifetimeAsync()
    {
        while (true)
        {
            float lifetime = Time.realtimeSinceStartup - startTime;
            Debug.Log($"オブジェクトの生存時間(秒): {lifetime:F2}");

            if (lifetime > MaxLifetime)
            {
                Debug.Log($"テストループを停止します。生存時間: {lifetime:F2}");
                break;
            }
            await Task.Delay(1000);
        }
    }
}

3. 詳細な解説

3.1 変数名と定数の設定

  • startTime
    • ゲームオブジェクトの開始時刻を Time.realtimeSinceStartup で記録しています。
    • 名前が直感的で、開始時刻であることが容易に理解できます。
  • MaxLifetime
    • 30秒を表す定数。
    • 定数化することで、閾値の変更が容易になり、保守性が向上します。

3.2 非同期メソッドの利用

  • async void Start()
    • Unityの Start() メソッドを非同期に定義することで、アプリケーション開始時に非同期処理を開始します。
    • 非同期メソッド内で await を使用することで、タスクの完了を待ちながらも、メインスレッドの処理をブロックしません。
  • await TrackLifetimeAsync()
    • TrackLifetimeAsync メソッドを呼び出し、その完了を待機します。
    • これにより、非同期処理の流れが明確になり、読みやすいコードとなります。

3.3 タイマー機能の実装

  • 無限ループ (while (true))
    • 毎回、現在の生存時間を Time.realtimeSinceStartup - startTime で計算し、ログ出力を行います。
  • 終了条件のチェックとループ終了
    • 生存時間が MaxLifetime(30秒)を超えた場合、ログ出力後に break 文でループを終了します。
  • 待機処理 (await Task.Delay(1000))
    • Task.Delay(1000) を使って1秒間非同期で待機し、ループが1秒ごとに実行されるようにしています。
    • この待機処理により、毎秒の更新を実現しつつ、メインスレッドをブロックしません。

3.4 Async/awaitのメリット

  • シンプルな非同期処理:
    • Async/awaitを利用することで、コルーチンに比べコードのフローが直線的になり、理解しやすい実装が可能になります。
  • エラーハンドリング:
    • 非同期メソッドでは通常の例外処理(try-catch)を利用できるため、エラーハンドリングが容易です。
  • 保守性:
    • コルーチンに比べ、非同期処理の制御が明示的になり、将来の機能追加や変更に柔軟に対応できます。

4. まとめ

この資料では、Unityにおける30秒監視機能を、従来のコルーチン方式からAsync/await方式にリファクタリングした例を紹介しました。

  • コードの概要:
    • ゲームオブジェクトの生存時間を毎秒ログ出力し、30秒経過後に処理を終了します。
  • 主な変更点:
    • コルーチンからAsync/awaitを利用する非同期メソッドへの置き換え
    • 変数名の明確化と定数の導入による保守性の向上
    • Task.Delay を利用したシンプルな待機処理
  • メリット:
    • コードが直線的で読みやすく、エラーハンドリングも容易になるため、開発現場での保守性や拡張性が向上します。

Async/awaitを使うことで、Unityの非同期処理における新たな可能性を探り、従来のコルーチンに加えて柔軟な実装手法を取り入れることができます。

Unity,非同期

Posted by hidepon