【Unity】Photon Fusionを使ってみた【マルチプレイ】
Photon Fusionとはなんぞや
PhotonのPUNとBoltがフュージョンして最強になったらしい。
とにかくなんかすごいらしい。
Photon公式でPUNとBoltをLegacyって書いちゃうくらいすごいらしい。
注意(2022/6/22追記)
WebGLには未対応とのこと。
UnityRoom向けにはPUNを使うしかない・・・
(追記)
Photon FusionがWebGLなどのプラットフォームに対応したみたいです!
これでUnityRoom向けにも作れるようになりました。
PUN2の対応していたプラットフォーム全てに、Fusion側も対応したみたいです!
参考にした記事
公式の解説「Fusion 100」
これを一通り終わらせたら理解が深まった。気がする。
インストール
ちなみにアセットストアにはまだ無いです。
こちらを参考に導入。
なのだが、SDKの配布ページのリンクが切れている。
右の「はじめよう」からSDK & Release Notesのリンク先からダウンロードできる。
注意
FusionをUnityにインポートした後に、フォルダの場所を変えるといろんなエラーが起こる。
原因は調査中。
ネットワークにつなぐ
空のゲームオブジェクトを作ってNetworkRunnerとNetworkSceneManager Defaultを貼り付ける。
NetworkRunnerがFusionで一番大事なクラスらしい。PUNで言うところのPhotonNetworkなのかな。
新しいスクリプトを作って(今回はSpawnerと命名)、INetworkRunnerCallbacksを継承させる。
これをさっきのNetworkRunnerと同じゲームオブジェクトに貼り付ける。
NetworkRunnerと同じところにあると、Runnerが勝手にINetworkRunnerCallbacksを継承したコンポーネントを拾ってくれる。
なので絶対にNetworkRunnerと同じとこに貼る。
using System;
using System.Collections;
using System.Collections.Generic;
using Fusion;
using Fusion.Sockets;
using UnityEngine;
public class Spawner : MonoBehaviour, INetworkRunnerCallbacks
{
public void OnPlayerJoined(NetworkRunner runner, PlayerRef player)
{
}
public void OnPlayerLeft(NetworkRunner runner, PlayerRef player)
{
}
public void OnInput(NetworkRunner runner, NetworkInput input)
{
}
public void OnInputMissing(NetworkRunner runner, PlayerRef player, NetworkInput input)
{
}
public void OnShutdown(NetworkRunner runner, ShutdownReason shutdownReason)
{
}
public void OnConnectedToServer(NetworkRunner runner)
{
}
public void OnDisconnectedFromServer(NetworkRunner runner)
{
}
public void OnConnectRequest(NetworkRunner runner, NetworkRunnerCallbackArgs.ConnectRequest request, byte[] token)
{
}
public void OnConnectFailed(NetworkRunner runner, NetAddress remoteAddress, NetConnectFailedReason reason)
{
}
public void OnUserSimulationMessage(NetworkRunner runner, SimulationMessagePtr message)
{
}
public void OnSessionListUpdated(NetworkRunner runner, List<SessionInfo> sessionList)
{
}
public void OnCustomAuthenticationResponse(NetworkRunner runner, Dictionary<string, object> data)
{
}
public void OnReliableDataReceived(NetworkRunner runner, PlayerRef player, ArraySegment<byte> data)
{
}
public void OnSceneLoadDone(NetworkRunner runner)
{
}
public void OnSceneLoadStart(NetworkRunner runner)
{
}
}
NetworkRunner.StartGame()でサーバーに接続できる。
GameModeにAuto~を指定。ホストかクライアントか自動で割り当ててくれる。
FusionはGameModeがたくさんあるのがウリらしいから、気になる方は調べてください。
SceneObjectProviderにNetworkSceneManagerDefaultを指定。これがなんなのかよくわからないけど、無かったらエラーを吐いたので書く。
private NetworkRunner _networkRunner;
private void Start()
{
_networkRunner = GetComponent<NetworkRunner>();
_networkRunner.ProvideInput = true;
_networkRunner.StartGame(new StartGameArgs()
{
GameMode = GameMode.AutoHostOrClient,
SceneObjectProvider = GetComponent<NetworkSceneManagerDefault>()
});
}
プレイヤーを生成する
適当なオブジェクトを作って(今回はキューブ)、Playerって名前にする。
NetworkObjectコンポーネントを貼り付けてからプレハブ化する。こいつがPUNで言うところのPhotonViewにあたるらしい。
なんかエラー吐いてるけどシーンを保存したら消えます。
さっきのSpawnerスクリプトに書き足す。
プレハブを参照させてから、OnPlayerJoined()関数の中身を書き足す。
[SerializeField] private NetworkPrefabRef prefabRef;
public void OnPlayerJoined(NetworkRunner runner, PlayerRef player)
{
runner.Spawn(prefabRef, Vector3.zero, Quaternion.identity, player);
}
PUNではクライアントが各自勝手にオブジェクトを生成してたけど、Fusionではホストにしか権限がないらしい。
誰かが入室したのをホストが察知→その人にオブジェクトを生成してあげる、といった形。
Spawn()関数の第4引数にちゃんとplayerを指定しわすれないように。
この引数は、そのオブジェクトに対する入力権限みたい。
Unityに戻って、Spawnerにプレハブ化したPlayerオブジェクトを参照させてあげる。
実行させたらプレイヤーオブジェクトが生成されるはず。
ビルドして確かめる
分かりやすいように、PlayerSettingでFullscreenModeをWindowedに、サイズは各々好きなように。
Run in Backgroundにもチェックを。
ビルドして、実行。
Unityでも実行。
UnityのヒエラルキーにPlayerが2人いたら成功。
おしまい
今回はここまで、公式サイトでは、位置同期やパラメーター同期、RPCなど、ほかにも独自の当たり判定などいろいろ書いてあるので気になる人は要チェック。