※たまにコードを改修しているため、説明が古くなっています
コード
説明
Second.ToTick()
// 秒単位 と Tick単位 の変換をします
public static int ToTick(this int second, NetworkRunner runner) => (int)(second / runner.DeltaTime);
public static int ToTick(this float second, NetworkRunner runner) => (int)(second / runner.DeltaTime);
public static float ToSecond(this int tick, NetworkRunner runner) => tick * runner.DeltaTime;
// Runner.Tick から second 秒経過した際の Tick を返します
public static int GetTickAfter(this NetworkRunner runner, float second) => runner.Tick + (int)(second / runner.DeltaTime);
// Runner.Tick が tick を超えてから経過した秒数を返します
public static float ElapsedTime(this NetworkRunner runner, int tick) => (runner.Tick - tick) * runner.DeltaTime;
// Runner.Tick が tick になるまでの秒数を返します
public static float RemainingTime(this NetworkRunner runner, int tick) => -runner.ElapsedTime(tick);
// Runner.Tick が tick を超えたかどうか判定します
public static bool HasPassed(this NetworkRunner runner, int tick) => (runner.Tick - tick) > 0;
public static bool HasReached(this NetworkRunner runner, int tick) => (runner.Tick - tick) >= 0;
public static bool IsAt(this NetworkRunner runner, int tick) => runner.Tick == tick;
public static bool HasntPassed(this NetworkRunner runner, int tick) => (runner.Tick - tick) <= 0;
public static bool HasntReached(this NetworkRunner runner, int tick) => (runner.Tick - tick) < 0;
Array
NetworkArray.ForLoop()
使用例.cs
NetArray.ForEach(item => Debug.Log(item));
NetArray.ForLoop((i, item) => Debug.Log(i + " : " + item));
NetworkArray.Replace()
NetworkArray の要素から一致する条件を探し、そこに value を代入します。
使用例.cs
// 全要素を -1 に変更
NetArray.ReplaceAll(-1);
// 全要素を 2 倍
NetArray.ReplaceAll(v => v * 2);
// -2 の要素を全て 0 に変更
NetArray.Replace(v => v == -2, 0);
// 0 の要素を1つだけ 100 に変更
int index = NetArray.ReplaceOne(v => v == 0, v => 100);
// 0 の要素3つを 100, 200, 300 に変更
bool success = NetArray.ReplaceOneByOne(v => v == 0, 100, 200, 300);
NetworkArray.OnValueChanged()
NetworkArray で変化した要素を探し、処理を行います。
使用例.cs
[Networked(OnChanged = nameof(OnChangedArray)), Capacity(16)] NetworkArray<int> Array { get; }
private static void OnChangedArray(Changed<ClassName> changed) => changed.Behaviour.ChangedArray(changed);
private void ChangedArray(Changed<ClassName> changed)
{
Array.OnValueChanged(changed, c => c.Array, (index, beforeValue, afterValue) => { /* 省略 */ } );
}
v2 は Changed の代わりに ChangeDetector で取得した前の値を引数に入れてください。
UniRx
TickTimer.OnCompleted()
使用例.cs
// 完了時に実行
tickTimer.OnCompleted(Runner).Subscribe(_ => { /* 省略 */ } ).AddTo(this);
// 有効の間、常に実行
tickTimer.OnUpdated(Runner).Subscribe(_ => { /* 省略 */ } ).AddTo(this);
// 有効の間、Runner.DeltaTime の間隔で実行
tickTimer.OnRunnerUpdated(Runner).Subscribe(_ => { /* 省略 */ } ).AddTo(this);
// RemainingTime の整数部分が更新された時に実行
tickTimer.OnCountDowned(Runner).Subscribe(_ => { /* 省略 */ } ).AddTo(this);
その他
Changed.LoadOld() ver1のみ
既存のChanged.LoadOld()
の利便性を高めました。
使用例.cs
var prevValue = changed.LoadOld(behaviour => behaviour.Value);
var newValue = changed.Behaviour.Value;
UpdateFlow()
Tick の経過時間に応じて実行する関数を変える処理を簡潔に書けます。
使用例.cs
void FixedUpdateNetwork()
{
Runner.UpdateFlow(ShotTick, new int[] { 5, 10, 5 }, BeforeShot, Shot, AfterShot);
}
void BeforeShot(int elapsedTick) => { /*省略*/ }
void Shot(int elapsedTick) => { /*省略*/ }
void AfterShot(int elapsedTick) => { /*省略*/ }
Runner.Host()
// Host の PlayerRef を取得します
public static PlayerRef Host(this NetworkRunner runner)
=> runner.GameMode == GameMode.Server ? PlayerRef.None : runner.Simulation.Config.DefaultPlayers - 1;
// 専用サーバか判定します。Host Mode と Server Mode を平行に実装する際、専用サーバに対して不要な処理を省く用途で利用します
public static bool IsServerMode(this NetworkRunner runner) => runner.GameMode == GameMode.Server;
PlayerRef.IsHost()
// PlayerRef が Host か判定します
public static bool IsHost(this PlayerRef playerRef, NetworkRunner runner) => playerRef == runner.Simulation.MaxConnections;
// PlayerRef が自分か判定します
public static bool IsMe(this PlayerRef playerRef, NetworkRunner runner) => playerRef == runner.LocalPlayer;
// PlayerRef が NetworkObject/NetworkBehaviour の 入力権限/所有権 を持っているか判定します
public static bool HasInputAuthorityTo(this PlayerRef playerRef, NetworkObject no) => playerRef == no.InputAuthority;
public static bool HasStateAuthorityTo(this PlayerRef playerRef, NetworkObject no) => playerRef == no.StateAuthority;
public static bool HasInputAuthorityTo(this PlayerRef playerRef, NetworkBehaviour nb) => playerRef == nb.Object.InputAuthority;
public static bool HasStateAuthorityTo(this PlayerRef playerRef, NetworkBehaviour nb) => playerRef == nb.Object.StateAuthority;
RpcInfo.Source()
Host/Server が RPC を呼ぶと RpcInfo.Source は None になります。
この拡張メソッドは、Host が RPC を呼んだ際に Host の PlayerRef を利用できるようにしたものです。
public static PlayerRef Source(this RpcInfo info, NetworkRunner runner) => info.Source.IsNone ? runner.Host() : info.Source;
NetworkBehaviour.GetSeed()
乱数のシード値として利用できる値を取得します。
(カスタムプロパティに seed を追加する必要があります)
使用例.cs
Random.InitState(networkBehaviour.GetSeed());
NetworkObject.TryAssignInputAuthority()
再接続や Host Migration を行う際、ConnectionToken を元に NetworkObject の入力権限の変更を試みます。
public static bool TryAssignInputAuthority(this NetworkObject obj, NetworkRunner runner, Guid token, bool noAssignment = true)
{
foreach (var p in runner.ActivePlayers)
{
if (new Guid(runner.GetPlayerConnectionToken(p)) != token) continue;
obj.AssignInputAuthority(p);
return true;
}
if (noAssignment) obj.AssignInputAuthority(PlayerRef.None);
return false;
}
PhotonFusionUtil
便利クラスも含めています。
Runner
どこからでも NetworkRunner を取得できます。
Runenr を複数利用している際は一つ目しか取れないので注意が必要です。
var runner = PhotonFusionUtil.Runner;