概要
Photon Fusion の TickTimer を便利に扱える拡張メソッドを作りました。
完了時にメッセージを飛ばしたり、秒刻みのカウントダウンを実装したりするのに役立ちます。
使用例
Enterキーを押したらゲーム開始のカウントダウンを始める.cs
private void Update()
{
if (Input.GetKeyDown(KeyCode.Return))
{
RpcReady(TickTimer.CreateFromSeconds(Runner, 5f));
}
}
public Subject<Unit> OnGameStarted { get; private set; } = new Subject<Unit>();
public Subject<int> OnCountDowned { get; private set; } = new Subject<int>();
[Rpc(RpcSources.StateAuthority, RpcTargets.All)]
private void RpcReady(TickTimer tickTimer)
{
tickTimer.OnCountDowned(Runner).Subscribe(OnCountDowned).AddTo(this);
tickTimer.OnCompleted(Runner).Subscribe(OnGameStarted).AddTo(this);
}
コード
お手持ちの PhotonFusionEx クラスに下記の関数を追加してご利用ください。
PhotonFusionEx.cs
using Fusion;
using System;
using System.Linq;
using UniRx;
using UnityEngine;
namespace Extensions
{
using Fusion;
using System;
using UniRx;
using UnityEngine;
namespace Extensions
{
public static class PhotonFusionEx
{
/// <summary>
/// Runner.Tick と tick との時間差
/// </summary>
public static float ElapsedTime(this NetworkRunner runner, int tick) => (runner.Tick - tick) * runner.DeltaTime;
/// <summary>
/// TickTimer が完了した時に実行
/// </summary>
public static IObservable<Unit> OnCompleted(this TickTimer tickTimer, NetworkRunner runner)
=> Observable.EveryUpdate().First(_ => tickTimer.Expired(runner)).Select(_ => Unit.Default);
/// <summary>
/// TickTimer が有効の間、常に実行
/// </summary>
public static IObservable<Unit> OnUpdated(this TickTimer tickTimer, NetworkRunner runner)
=> Observable.EveryUpdate().TakeWhile(_ => !tickTimer.Expired(runner)).Select(_ => Unit.Default);
/// <summary>
/// TickTimer の RemainingTime が更新された時に実行
/// </summary>
public static IObservable<float> OnRunnerUpdated(this TickTimer tickTimer, NetworkRunner runner)
=> Observable.EveryUpdate()
.TakeWhile(_ => !tickTimer.Expired(runner))
.Select(_ => tickTimer.RemainingTime(runner).Value)
.DistinctUntilChanged();
/// <summary>
/// TickTimer の RemainingTime の整数部分が更新された時に実行
/// </summary>
public static IObservable<int> OnCountDowned(this TickTimer tickTimer, NetworkRunner runner, int minCount = 1, int maxCount = int.MaxValue)
=> Observable.EveryUpdate()
.TakeWhile(_ => !tickTimer.Expired(runner))
.Select(_ => Mathf.CeilToInt(tickTimer.RemainingTime(runner).Value))
.DistinctUntilChanged()
.Where(count => count >= minCount && count <= maxCount);
}
}
}