LoginSignup
1
1

More than 1 year has passed since last update.

【Unity】Photon Fusion の TickTimer に関する処理を UniRx で簡潔に実装できる拡張メソッド

Last updated at Posted at 2022-11-19

概要

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);
        }
    }
}
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1