いくつかの要因で変化する Networked プロパティに対して、過剰に細かくイベントを設定できるクラスを書いてみました。
実用的ではなく動作も未確認ですが、初学者の参考になれば幸いです。
SelfChangeDetector.cs
using Fusion;
using System;
public class SelfChangeDetector<T>
{
/// <summary> Reliable value </summary>
public T Value { get; private set; }
/// <summary> Client predicted value </summary>
public T AlphaValue { get; private set; }
/// <summary> Action invoked when the value changes </summary>
public event Action<T, T> OnChanged;
/// <summary> Action invoked when the value actually changes </summary>
public event Action<T, T> OnActuallyChanged;
/// <summary> Action invoked when the value changes in client prediction </summary>
public event Action<T, T> OnAlphaChanged;
/// <summary> Action invoked when client predicted value is changed in rollback </summary>
public event Action<T, T> OnRollBackChanged;
/// <summary> Action invoked when the value changes at the timing of isForward </summary>
public event Action<T, T> OnForwardChanged;
public SelfChangeDetector(T defaultValue)
{
Value = defaultValue;
AlphaValue = defaultValue;
}
/// <summary> Run it with FixedUpdateNetwork() </summary>
public void Update(T defaultValue, NetworkBehaviour nb) => Update(defaultValue, nb.Runner, nb.HasStateAuthority);
/// <summary> Run it with FixedUpdateNetwork() </summary>
public void Update(T defaultValue, NetworkRunner runner) => Update(defaultValue, runner, runner.IsServer || runner.IsSharedModeMasterClient);
/// <summary> Run it with FixedUpdateNetwork() </summary>
public void Update(T networkedProperty, NetworkRunner runner, bool hasStateAuthority)
{
if (hasStateAuthority)
{
if (Value.Equals(networkedProperty) == false)
{
OnChanged?.Invoke(Value, networkedProperty);
OnActuallyChanged?.Invoke(Value, networkedProperty);
OnForwardChanged?.Invoke(Value, networkedProperty);
Value = networkedProperty;
}
return;
}
if (runner.IsFirstTick && runner.IsResimulation)
{
if (AlphaValue.Equals(networkedProperty) == false)
{
OnChanged?.Invoke(AlphaValue, networkedProperty);
OnRollBackChanged?.Invoke(AlphaValue, networkedProperty);
AlphaValue = networkedProperty;
}
if (Value.Equals(networkedProperty) == false)
{
OnActuallyChanged?.Invoke(Value, networkedProperty);
Value = networkedProperty;
}
return;
}
if (AlphaValue.Equals(networkedProperty) == false)
{
OnChanged?.Invoke(AlphaValue, networkedProperty);
OnAlphaChanged?.Invoke(AlphaValue, networkedProperty);
if (runner.IsForward) OnForwardChanged?.Invoke(AlphaValue, networkedProperty);
AlphaValue = networkedProperty;
}
}
}