📗
【Unity】UniRx/UniTask大全
はじめに
初めての方も、そうでない方もこんにちは!
現役ゲームプログラマーのたむぼーです。
自己紹介を載せているので、気になる方は見ていただければ嬉しいです!
今回は
UnityのUniRx/UniTask大全
として、僕がよく使う機能を紹介します
導入方法
https://github.com/neuecc/UniRx.git?path=Assets/Plugins/UniRx/Scripts
https://github.com/Cysharp/UniTask.git?path=src/UniTask/Assets/Plugins/UniTask
導入手順
UPM(Unity Package Manager)で追加します
Window → Package Manager → + → Add pacage from git URL
UniRx
■AddToについて
AddToとはAddToの引数に指定されたオブジェクトが破棄されたタイミングで、Subscribeで生成された購読処理をDisposeするための関数
■クリック処理
・クリックした
_button.OnClickAsObservable().Subscribe(
_ => Debug.Log("クリックした処理");
).AddTo(this);
・クリック開始
_button.OnPointerDownAsObservable().Subscribe(
_ => Debug.Log("クリック開始した処理");
).AddTo(this);
・クリック終了
_button.OnPointerUpAsObservable().Subscribe(
_ => Debug.Log("クリック終了した処理");
).AddTo(this);
■オブジェクトの破壊時処理
・objが破壊されたときの処理
obj.OnDestroyAsObservable().Subscribe(
_ => Debug.Log("obj破壊時の処理");
).AddTo(this);
UniTask
■待機
・イベントまで待つ
// _isEventがtrueになるまで待つ
await UniTask.WaitUntil(() => _isEvent);
・更新タイミングでイベントまで待つ
// Updateのタイミングで_isEventがtrueになるまで待つ
await UniTask.WaitUntil(() => _isEvent, PlayerLoopTiming.Update);
・時間まで待つ
// _waitTimeの指定秒数まで待つ
await UniTask.Delay(TimeSpan.FromSeconds(_waitTime));
・更新タイミングで時間まで待つ
// Updateのタイミングで_waitTimeの指定秒数まで待つ
await UniTask.Delay(
TimeSpan.FromSeconds(_waitTime),
delayTiming: PlayerLoopTiming.Update
);
・1フレームまで待つ
// 1フレームだけ待つ
await UniTask.Yield();
・更新タイミングまで待つ
// Updateのタイミングまで待つ(更新タイミングは色々ある
await UniTask.Yield(PlayerLoopTiming.Update);
・指定フレームまで待つ
// _frameのフレーム数だけ待つ
await UniTask.DelayFrame(_frame);
・更新タイミングで指定フレームまで待つ
// Updateのタイミングで_frameのフレーム数だけ待つ
await UniTask.DelayFrame(_frame, PlayerLoopTiming.Update);
・すべて完了するまで待つ
// runActionとrunWaitUntilが完了するまで待機
UniTask runAction = UniTask.Run(() => onAction?.Invoke());
UniTask runWaitUntil = UniTask.WaitUntil(() => _isEvent);
await UniTask.WhenAll(runAction, runWaitUntil);
【おまけ】UniTaskのキャンセル補助する処理
CancellationTokenHelper.cs
using System.Threading;
namespace Utils
{
public class CancellationTokenHelper
{
/// <summary> Cts </summary>
public CancellationTokenSource Cts { get; private set; }
/// <summary> Ctsトークン </summary>
public CancellationToken Token => Cts.Token;
/// <summary>
/// コンストラクタ
/// </summary>
public CancellationTokenHelper()
{
Reset();
}
/// <summary>
/// デストラクタ
/// </summary>
~CancellationTokenHelper()
{
Dispose();
}
/// <summary>
/// リセット
/// </summary>
public void Reset()
{
Dispose();
Cts = new CancellationTokenSource();
}
/// <summary>
/// 破棄
/// </summary>
public void Dispose()
{
if (Cts != null)
{
Cts.Cancel();
Cts.Dispose();
Cts = null;
}
}
}
}
使い方
using UnityEngine;
using Cysharp.Threading.Tasks;
using System.Threading;
namespace Example
{
public class ExampleUniTask
{
private bool _isInitialize = false;
private CancellationTokenHelper _ctsHelper;
/// <summary>
/// 初期化
/// </summary>
public void Initialize()
{
if (_isInitialize)
{
return;
}
// ヘルパーのインスタンスを生成
_ctsHelper = new CancellationTokenHelper();
// UniTaskの関数に引数でTokenを渡す
ExampleUniTaskAsync(_ctsHelper.Token).Forget();
_isInitialize = true;
}
/// <summary>
/// 廃棄
/// </summary>
public void Dispose()
{
// 不要になったらDisposeする
_ctsHelper.Dispose();
_isInitialize = false;
}
/// <summary>
/// 非同期でバックボタンの同期
/// </summary>
private async UniTaskVoid ExampleUniTask(CancellationToken token)
{
// キャンセルしていない時はループ
while (! token.IsCancellationRequested)
{
// Updateまで待機
await UniTask.Yield(PlayerLoopTiming.Update, token);
}
}
}
}
Discussion