インターポレータ
概要
インターポレータは、Render()、LateUpdate()、 Update()を使用する場合に、スナップショットおよびネットワークプロパティの内挿データへのアクセスを可能にするものです。返されるステートやネットワークプロパティの内挿データは、NetworkBehaviour.InterpolationDataSourceのタイムフレームを考慮しています。
使用可能なインターポレータには2通りあります。
- Interpolator<T>: ネットワークプロパティのFrom値とTo値、自動化内挿ハンドリングの内挿データへのアクセサ。
- RawInterpolator: ネットワークプロパティのFrom値とTo値、内挿データへのアクセサ。適切なバッキングタイプへのキャスティングを必要とする。
備考: RawInterpolator インターポレータは安全でないコードを必要とします。
Interpolator<T>
ネットワークプロパティのFrom値とTo値へのアクセサを作成し、自動化内挿ハンドリングの内挿データを公開します。
GetInterpolator<T>(string propertyName)
NetworkBehaviourインスタンス呼び出しの特定のプロパティに、キャッシュ可能なInterpolator<T>を返します。
値
NetworkBehaviour.InterpolationDataSourceによって指定されたタイムフレームを使用して、関連ネットワークプロパティに内挿値を返すであろうValueプロパティを公開します。
GetValues() および TryGetValues()
スナップショット値および内挿データはGetValues()メソッドまたはTryGetValues()メソッドでも取得可能です。これらのメソッドは、カスタム内挿ハンドリングでFrom値、To値、浮動アルファ値(Lerpのt値)を返すものです。デフォルトで使用されるタイムフレームはNetworkBehaviour.InterpolationDataSourceで指定されますが、ローカル/force = true引数で予測去れたタイムフレームを具体的に使用するように上書きすることができます。
ハンドリング可能なタイプ
可能なタイプは以下の通りです。
- float
- Vector3
- Vector2
- int (ランディング発生)
- bool (重要: ブーリアン値が内挿できないため、From値が返されます。)
- NetworkBool (重要: ブーリアン値が内挿できないため、From値が返されます。)
使用例
C#
public class InterpolatorExample : NetworkBehaviour
{
  public float DegreesPerSecond = 360f;
  [Networked]
  public float Rotation { get; set; }
  public Interpolator<float> NetFloatInterpolator;
  public override void Spawned() {
    NetFloatInterpolator = GetInterpolator<float>(nameof(Rotation));
  }
  public override void FixedUpdateNetwork() {
    // Rotate the object at a fixed rate for each tick.
    Rotation += DegreesPerSecond * Runner.DeltaTime;
  }
  public override void Render() {
    // Get the interpolated value.
    // Note that Value uses the timeframe specified by the InterpolationDataSource value.
    transform.rotation = Quaternion.Euler(0, 0, NetFloatInterpolator.Value);
  }
}
RawInterpolator
Interpolator<T>が対応していないタイプでは、RawInterpolatorがネットワークプロパティスナップショットステートへの安全でないアクセスを、RawInterpolator.GetValues()メソッドと共に現在のレンダリングタイムフレームの内挿情報と共に許可します。
GetValues() および TryGetValues()
スナップショット値および内挿データはGetValues()メソッドまたはTryGetValues()メソッドでも取得可能です。これらのメソッドは、カスタム内挿ハンドリングでFrom値、To値、浮動アルファ値(Lerpのt値)を返すものです。デフォルトで使用されるタイムフレームはNetworkBehaviour.InterpolationDataSourceで指定されますが、ローカル/force = true引数で予測去れたタイムフレームを具体的に使用するように上書きすることができます。
このモードが安全ではなく、ポインタが使用されているため、From値、To値は適切なプロパティタイプへキャストする必要があります。
GetInterpolator(string propertyName)
NetworkBehaviourインスタンス呼び出しの特定のプロパティに、キャッシュ可能なRawInterpolatorを返します。
C#
public struct CustomStruct : INetworkStruct
{
  public Vector3    Position;
  public Quaternion Rotation;
}
public unsafe class RawInterpolatorExample : NetworkBehaviour
{
  [Networked]
  public CustomStruct Data { get; set; }
  RawInterpolator _dataInterpolator;
  public override void Spawned()
  {
    _dataInterpolator = GetInterpolator(nameof(Data));
  }
  public override void Render()
  {
    if (_dataInterpolator.TryGetValues(out var f, out var t, out var alpha))
    {
      var from = (CustomStruct*) f;
      var to   = (CustomStruct*) t;
      transform.position = Vector3.Lerp(from->Position, to->Position, alpha);
    }
  }
}```
### Network Collections
The RawInterpolator has methods specifically for getting the `From` snapshot, `To` snapshot, and interpolation alpha data from Fusion's collection types:
* TryGetArray<T>(),
* TryGetDictionary<T>()
* TryGetLinkedList<T>()
```csharp
using UnityEngine;
using Fusion;
public class CollectionRawInterpolator : NetworkBehaviour
{
  [Networked, Capacity(8)]
  public NetworkArray<float> NetArray { get; } = MakeInitializer(new float[8] { 0, 1, 2, 3, 4, 5, 6, 7 });
  RawInterpolator _interpolator;
  public override void Spawned()
  {
    // Get the RawInterpolator for our property
    _interpolator = GetInterpolator(nameof(NetArray));
  }
  public override void FixedUpdateNetwork()
  {
    // Increment each value by one every tick.
    for (int i = 0; i < NetArray.Length; i++)
    {
      NetArray.Set(i, NetArray[i] + 1);
    }
  }
  public override void Render()
  {
    // Get the From, To and alpha data, and manually interpolate the values
    if (_interpolator.TryGetArray(NetArray, out var from, out var to, out float alpha))
    {
      var str = $"alpha: {alpha} values: \n";
      for (int i = 0; i < NetArray.Length; i++) {
        var lerped = Mathf.Lerp(from[i], to[i], alpha);
        str +=  $"{from[i]} -> {to[i]} = {lerped}\n";
      }
      Debug.Log(str);
    }
  }
}