ボタンがひとつの場合
[SerializeField]
private Button _button1;
void Start()
{
StartCoroutine(WaitButtonClick(_button1));
}
IEnumerator WaitButtonClick(Button button)
{
yield return button.OnClickAsObservable().First().ToYieldInstruction();
Debug.LogFormat("{0} がクリックされました", button.name);
}
ボタンがふたつの場合
どちらのボタンが押されたのかも取得できるようにします。
[SerializeField]
private Button _button1;
[SerializeField]
private Button _button2;
void Start()
{
StartCoroutine(WaitButtonClick(_button1, _button2));
}
IEnumerator WaitButtonClick(Button button1, Button button2)
{
var s = Observable.Merge(button1.OnClickAsObservable().Select(_ => button1),
button2.OnClickAsObservable().Select(_ => button2));
var y = s.First().ToYieldInstruction();
yield return y;
Debug.LogFormat("{0} がクリックされました", y.Result.name);
}
ボタンが 3 つ以上の場合
[SerializeField]
private Button _button1;
[SerializeField]
private Button _button2;
[SerializeField]
private Button _button3;
void Start()
{
StartCoroutine(WaitButtonClick(_button1, _button2, _button3));
}
IEnumerator WaitButtonClick(params Button[] buttons)
{
var y = buttons.Select(b => b.OnClickAsObservable().Select(_ => b))
.Aggregate((a, b) => a.Merge(b))
.First()
.ToYieldInstruction();
yield return y;
Debug.LogFormat("{0} がクリックされました", y.Result.name);
}
タイムアウトを設けてキャンセルできるようにする
Timeout
メソッドを使うと、タイムアウトするまでの時間が設定できます。
IEnumerator WaitButtonClick(int timeoutSeconds, params Button[] buttons)
{
var y = buttons.Select(b => b.OnClickAsObservable().Select(_ => b))
.Aggregate((a, b) => a.Merge(b))
.Timeout(TimeSpan.FromSeconds(timeoutSeconds)) // timeoutSeconds 秒でタイムアウト
.First()
.ToYieldInstruction(throwOnError: false);
yield return y;
if (y.HasError)
{
if (y.Error is TimeoutException)
{
Debug.LogFormat("タイムアウトしました");
}
}
else
{
Debug.LogFormat("{0} がクリックされました", y.Result.name);
}
}
ToYieldInstruction
の引数に CancellationToken
を渡して、外部からキャンセルできるようにする
class Canceller : ICancelable
{
private bool _isDisposed;
public bool IsDisposed { get { return _isDisposed; } }
public void Dispose()
{
_isDisposed = true;
}
}
private void Start()
{
var canceller = new Canceller();
// _button0 をクリックしたらキャンセル
_button0.onClick.AddListener(() => canceller.Dispose());
StartCoroutine(WaitButtonClick(new CancellationToken(canceller), _button1, _button2, _button3));
}
IEnumerator WaitButtonClick(CancellationToken cancel, params Button[] buttons)
{
var y = buttons.Select(b => b.OnClickAsObservable().Select(_ => b))
.Aggregate((a, b) => a.Merge(b))
.First()
.ToYieldInstruction(cancel);
yield return y;
if (y.IsCanceled)
{
Debug.LogFormat("キャンセルされました");
}
else
{
Debug.LogFormat("{0} がクリックされました", y.Result.name);
}
}