This document is about: FUSION 2
SWITCH TO

Fusion 1からの移行

新機能

Fusion 2では、Fusionの基本原則をそのままに、APIを拡張する様々な新機能や改善点が盛り込まれました。以下は、特に重要な改善点のリストです。

Interest Enter/Exit コールバック

新しくIInterestEnterコールバックとIInterestExitコールバックが追加されました。これらは、ネットワークオブジェクトが特定のプレイヤーのAOI領域に出入りした時、プレイヤーがオブジェクトを明示的に関心対象に追加・削除した時に(Runner.SetPlayerAlwaysInterested()を使用して)呼び出されます。このコールバックは、各モード(サーバーモード・ホストモード・共有モード)のサーバー上で計算され、信頼性があります。

Interpolation Target

Fusion 1のInterpolation Targetは、正しく扱うことが困難な場合(特にネットワークオブジェクトをネストした時など)がありました。Fusion 2では補間がシンプルになりました。Interpolation Targetは削除されて、かわりにNetworkTransformが追加されているオブジェクト自体のTransformが補間されます。

NetworkTransform

NetworkTransformにはいくつかの変更がありました。Network Transformのページを参照してください。

ローカル座標系

NetworkTransformのTRSデータ(Position/Rotation/Scale)は、ローカル座標系で格納されるようになりました。

  • 子要素やネストしたNetworkTransformのデータ効率が大幅に向上
  • ネストしたNetworkTransformのAOIの位置は無効になるが、NetworkObjectAreaOfInterestOverrideから別のNetworkObjectの位置を指定して、プレイヤーの関心対象を決定することができる

スケールの同期

transform.localScaleを任意で同期できるようになりました。

親子関係の同期

NetworkObjectの親(Parent)を任意で同期できるようになりました。親には有効なNetworkBehaviourが存在し、NetworkTransformはネットワークオブジェクトのルートにある必要があります。

物理演算のネットワーク対応

Fusion 1のSDKにはNetworkRigidBodyNetworkPhysicsSimulationが含まれていましたが、これらはFusionのDLLから削除され、Unity Physics Addonに置き換わります。既存のServer OnlyモードとClient Predictionモードに加えて、Forward Onlyモードが追加される予定です。

アドオンはソースコードで提供しているので、プロジェクトのニーズに合わせて修正・拡張することができます。そのため、VRゲームのような複雑なユースケースでも、より柔軟に物理演算を動作させることができます。Fusion 2ではNetworkTransformからInterpolation Targetが削除されましたが、NetworkRigidbodyにはInterpolation Targetプロパティが残されています。ただし、Interpolation Targetが必要になるのは非常に特殊なユースケースのみになるため、通常はnullのままで問題ありません。

変更検知(Change Detection)

新しい変更検知APIによって、Renderでの変更の検知だけでなく、FixedUpdateNetworkでのゲームプレイロジックの判定のトリガーにも使用できるようになりました。これはより完全で柔軟なものですが、以前のOnChangedのように動作するシンプルなシンタックスシュガーを提供するかどうかを検討中です。

共有モードのティック

共有モードのティックが正確(Tick-Accurate)になりました。これによって様々な改善がもたらされます。

  • 共有モードにおける補間が、より機敏で正確になりました
  • 共有モードでもTickTimerが有効に機能するようになりました
  • 共有モードでTickの値が意味を持つようになりました

カスタム補間

新しい補間APIが追加されました。Fusionがネットワークプロパティを補間する時に使用する、開始値・終了値・補間係数を取得することができます。

ラグ補償の改善

ラグ補償が改善されました。過去のレンダリング情報から正しく補間されたアニメーション位置を自動的に使用するようになったため、レンダリング前にアニメーションのヒットボックスを調整する必要が無くなりました。さらにラグ補償は、2Dの物理シーンに対するクエリに対応するようになりました。

Fusion 2へのアップグレード

説明動画(英語)

以下は、シンプルなFusionプロジェクトのアップグレード手順を説明したチュートリアル動画(英語)です。

Unityバージョンのアップグレード

Fusion 2は、Unity 2021.x以降のバージョンに対応しています。古いバージョンのUnityを使用しているプロジェクトは、Unityをアップグレードした後にFusionをアップグレードしてください。

Fusion SDKのアップグレード

  1. プロジェクトをアップグレードする前に、バージョン管理システム等でプロジェクトをバックアップします。
  2. NetworkProjectConfigをバックアップ(Assets/Photon/Fusion/Resources/NetworkProjectConfigからAssets/NetworkProjectConfigに移動)します。
  3. プロジェクトから/Photonフォルダを削除します。
  4. Fusion 2 SDKをダウンロードしてUnityにインポートします。
  5. NetworkProjectConfigAssets/Photon/Fusion/Resources/NetworkProjectConfigに戻します。
  6. Fusion 2はFusion 1とは別のAppIdが必要です。新しいAppIdを作成して、「Fusion 2」を選択します。新しいAppIdは、UnityのFusion > Fusion Hubで入力します。
  7. /Packages/manifest.jsonを開き、既存のaddressablesパッケージを"com.unity.addressables": "1.21.12"に書き換えて(あるいは新しく追加して)、ファイルを保存します。

パッケージのインポートが完了すると、コンソールに多くのエラーが表示されます。これらのエラーは、APIを手動で修正する必要があります。

APIの変更

対応表

Previous API New API
(int)PlayerRef PlayerRef.PlayerId
PlayerRef.IsValid PlayerRef.IsRealPlayer
(int)SceneRef SceneRef.FromIndex
NetworkObject.NetworkGuid NetworkObject.NetworkTypeId
INetworkObjectPool INetworkObjectProvider.
NetworkTransform/NetworkTRSP.TeleportToPosition() NetworkTransform.Teleport()
Runner.Config.DefaultPlayers Runner.Config.Simulation.PlayerCount
[Accuracy] Remove the attribute. No replacment.
NetworkRunner.IsVisible NetworkRunner.GetVisible() and SetVisible()
Runner.SimulationConfig.Topology Runner.Topology
NetworkCharacterControllerPrototype NetworkCharacterController
Runner.Simulation.X (Runner.Simulation.Tick) Runner.X (Runner.Tick)
Runner.MultiplePeerUnityScene Runner.SimulationUnityScene
Runner.SetActiveScene Runner.LoadScene (must only be called on host/master client)
RunnerVisibilityNodes RunnerEnableVisibility

NetworkObjectPool

オブジェクトプールのAPIは、非同期ロードを可能にするため大幅に変更され、INetworkObjectPoolからINetworkObjectProviderに名前が変更されました。

新しく追加された二つのメソッドは、シンプルなユースケースの使用に適しています。

C#

public class PooledNetworkObjectProvider : NetworkObjectProviderDefault
{
    protected override NetworkObject InstantiatePrefab(NetworkRunner runner, NetworkObject prefab)
    {
        // Get object from pool and return it.
    }

    protected override void DestroyPrefabInstance(NetworkRunner runner, NetworkPrefabId prefabId, NetworkObject instance)
    {
        // Return the instance to the pool.
    }
}

ReleaseinstanceAcquireInstanceは調整されて、

C#

public void ReleaseInstance(NetworkRunner runner, NetworkObject no, bool isSceneObject)
{
    ....
}

から、

C#

public void ReleaseInstance(NetworkRunner runner, in NetworkObjectReleaseContext context)
{
    var no = context.Object;
}

になります。AcquireInstance(NetworkRunner runner, NetworkPrefabInfo info)は、AqcuirePrefabInstance(NetworkRunner runner, in NetworkPrefabAcquireContext context, out NetworkObject result)になります。戻り値はオブジェクトではなく結果(NetworkObjectAcquireResult.Success)として返され、オブジェクトはoutパラメーターで渡されます。

IsSceneObjectcontext.TypeId.IsSceneObjectに置き換えられます。

C#

public NetworkObject AcquireInstance(NetworkRunner runner, NetworkPrefabInfo info)
{
    NetworkObject prefab;
    if (NetworkProjectConfig.Global.PrefabTable.TryGetPrefab(info.Prefab, out prefab))
    {
        var newO = ...
        return newO;
    }
    return null;
}

は、以下のようになります。

C#

public NetworkObjectAcquireResult AcquirePrefabInstance(NetworkRunner runner, in NetworkPrefabAcquireContext context, out NetworkObject result)
{
    NetworkObject prefab;
    if (NetworkProjectConfig.Global.PrefabTable.TryGetPrefab(context.PrefabId, out prefab, true) == NetworkPrefabTableGetPrefabResult.Success)
    {
        var newO = ....
        result = newO;
        return NetworkObjectAcquireResult.Success;
    }

    result = null;
    return NetworkObjectAcquireResult.Failed;
}

NetworkProjectConfig.Global.PrefabTable.TryGetPrefab(info.Prefab, out prefab)は、bool isSynchronousパラメーターが追加されて、boolのかわりにNetworkPrefabTableGetPrefabResultを返すようになりました。

変更検知(Change Detection)

Fusion 2ではOnChangedは削除されましたが、より優れた新しいAPIによって、RenderFixedUpdateNetworkの両方で変更を検知できるようになりました。新しい変更検知APIの詳細についてはこちらを参照してください。

シンプルな例として、OnChangedを同等のRenderでの変更検知処理に置き換えると、

C#

public class Example : NetworkBehaviour
{
    [Networked(OnChanged = nameof(OnStateChanged))]
    public int State { get; set; }
    
    public static void OnStateChanged(Changed<Example> changed)
    {
        var value = changed.Behaviour.State;

        changed.LoadOld;
        var oldValue = changed.Behaviour.State;
    }
}

は、以下のようになります。

C#

public class Example : NetworkBehaviour
{
    private ChangeDetector _changes;
    
    [Networked]
    public int State { get; set; }

    public override void Spawned()
    {
        _changes = GetChangeDetector(ChangeDetector.Source.SimulationState);
    }

    public override void Render()
    {
        foreach (var change in _changes.DetectChanges(this, out var previousBuffer, out var currentBuffer))
        {
            switch (change)
            {
                case nameof(State):
                    var reader = GetPropertyReader<int>(nameof(State));
                    var (previous,current) = reader.Read(previousBuffer, currentBuffer);
                    OnStateChanged(previous, current);
                    break;
            }
        }
    }

    private void OnStateChanged(int oldValue,int value)
    {
    }
}

OnChangedRender

ChangeDetectorを使用するかわりに、ネットワークプロパティの個別の属性に対してOnChangedRenderを使用することもできます。これにより、ネットワークプロパティの変更を検知した時に、指定したメソッドを呼び出すことができます。

以下がその例です。

C#

public class Example : NetworkBehaviour
{
    [Networked, OnChangedRender(nameof(OnColorChanged))]
    public Color NetworkedColor  { get; set; }
    
    public Material material;

    public void OnColorChanged()
    {
        material.color = NetworkedColor;
    }
}

OnChangedRenderChangeDetectorの手軽な代替方法ですが、柔軟性に欠けるため、ゲームプレイに大きく影響を与えない要素向けになります。変更前の状態の取得には対応していないため、オブジェクトがスポーンした時に検知したい変更(オブジェクトの色や表示名の設定など)が見逃されてしまう問題が起こる可能性があり、その場合はSpawnedでの確認が必要です。

Interpolation Target

Interpolation Targetは削除されたため、NetworkTransformで使用する必要が無くなりました。NetworkTransformが付いたオブジェクトは、オブジェクト自体がRenderで適切に補間されます。

予測スポーン(Predicted Spawning)

予測スポーンは削除され、代替のAPIもありません。NetworkObjectPredictionKeyは不要になったので、Spawnメソッドから削除してください。

物理演算

NetworkRigidBodyNetworkPhysicsSimulationはFusionのDLLから削除され、Unity Physics Addonに置き換えられました。IBeforePhysicsStep等も削除されているため、RunnerPhysicsSimulate.OnBeforeSimulate等に修正する必要があります。

共有モードの改善

ティックが正確になったので、Runner.Tickを使用して特定のティックを参照し、他のクライアントと情報を共有することができます。また、TickTimerも使用できるようになりました。

Simulation Behaviour

SimulationBehaviourNetworkObjectでは使用できなくなりました。SimulationBehaviourNetworkBehaviourに置き換え、IOnSpawnedIOnDespawnedインターフェースを削除してSpawnedDespawnedをオーバーライドしてください。

プロキシ上のFixedUpdateNetwork

デフォルトでFixedUpdateNetworkはプロキシ上では実行されなくなりました。(プロキシとは、クライアント上でそのクライアントが入力権限を持たないネットワークオブジェクト)

Runner.SetIsSimulated(Object, true)を呼び出して、手動でFixedUpdateNetworkを有効にすることができます。確実にFixedUpdateNetworkが実行されることを保証するなら、SpawnedFixedUpdateNetworkを有効にすると良いでしょう。

シーン管理

シーン管理は大幅に変更されて、AddressableなシーンとAdditiveなロードが可能になりました。

プロトタイピング用のアドオン

Fusion 2は、プロトタイピング用のアドオンをサポートしません。移行するプロジェクトでこのアドオンを利用している場合は、SDKのアップグレードに従ってFusionのフォルダを削除する前に、アドオンを別フォルダに退避してください。大半のスクリプトはこのページを参考に修正できますが、不要なものは削除して、必要に応じて簡略化したバージョンで書き直すことを推奨します。

OrderAfter / OrderBefore

[OrderAfter][OrderBefore]属性は削除されました。かわりに、Unityの実行順序が使用されます。Edit > Project Settings > Script Execution Orderから、Fusionの型のScript Execution Orderを確認できます。Fusionの型の実行順序は絶対に変更しないでください

スクリプトの実行順序を調整するには、プロジェクト設定のリストに手動で追加するか、[DefaultExecutionOrder(x)]属性を使用してください。

例えば、[OrderAfter(typeof(HitboxManager))][DefaultExecutionOrder(-1995)]になります。

AOI INetworkRunnerCallbacks

新しく追加された二つのコールバックは、オブジェクトがクライアントのAOI領域に入ったり出たりした時に呼び出されます。これらはオブジェクトの表示・非表示を適切に切り替えるために使用できます。(Fusion 1では手動の検知が必要でした)

C#

public void OnObjectExitAOI(NetworkRunner runner, NetworkObject obj, PlayerRef player)
{
}

public void OnObjectEnterAOI(NetworkRunner runner, NetworkObject obj, PlayerRef player)
{
}
Back to top