目錄
大家好,我是Wilson,繼上次的教學之後,這次要分享的是如何快速地建立連線,並認識Fusion基本的連線架構。
領取Photon Fusion 快速上手懶人攻略
這邊幫大家準備了【Photon Fusion 快速上手懶人攻略】!
裡面介紹了Fusion的基本功能,以及Fusion同步網路狀態的3大方法,有興趣的朋友可以免費領取喔!
重點回顧
- Network Runner是Fusion連線的核心、心臟,所有的連線都必須依賴他,因此要在最一開始時,先建立在場景上,也因為整個遊戲只需要一個Network Runner,所以Network Runner預設是一個Don ‘t Destory On Load物件
- 每一個網路物件都需要有Network Object元件
- 透過Runner的StartGame()方法可以開啟新的Session(房間),並傳入必要參數:
- GameMode:以什麼模式加入房間,可以是Server、Host、Client、AutoHostOrClient、Single
- Session Name:房間名稱
- Scene:當前的場景
- Scene Manager:負責處理Fusion場景控制的物件,有特殊需求的話可以自己寫,但目前我們先使用Fusion提供的NetworkSceneManagerDefault就可以了。
- 實作INetworkRunnerCallbacks的物件會在重要的事件發生時,執行Callback的內容,如每當有玩家進入/離開房間時,會執行OnPlayerJoined/OnPlayerLeft,並傳入當前場景中的Network Runner及該名玩家的資料
- 為了讓物件的移動更順滑,我們會將擁有網路元件的物件作為空物件,真正的視覺物件放在其底下當子物件,再把視覺物件放到網路元件裡面的Interplation Target。
- 在網路上的物件生成/消除必須使用Runner的Spawn()以及Despawn()方法。Spawn()方法可以將生成出來的網路物件的Input Authority提拱給指定玩家(PlayerRef)。
- 使用Dictionary紀錄玩家資料以及其控制的角色物件,是為了之後方便追蹤。
Code
任何實作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) { }
public void OnHostMigration(NetworkRunner runner, HostMigrationToken hostMigrationToken) { }
BasicSpawner.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Fusion;
using Fusion.Sockets;
using System;
using UnityEngine.SceneManagement;
public class BasicSpawner : MonoBehaviour, INetworkRunnerCallbacks
{
[SerializeField]
private NetworkRunner networkRunner = null;
[SerializeField]
private NetworkPrefabRef playerPrefab;
private Dictionary<PlayerRef, NetworkObject> playerList = new Dictionary<PlayerRef, NetworkObject>();
private void Start()
{
StartGame(GameMode.AutoHostOrClient);
}
async void StartGame(GameMode mode)
{
networkRunner.ProvideInput = true;
await networkRunner.StartGame(new StartGameArgs()
{
GameMode = mode,
SessionName = "Fusion Room",
Scene = SceneManager.GetActiveScene().buildIndex,
SceneManager = gameObject.AddComponent<NetworkSceneManagerDefault>()
});
}
public void OnPlayerJoined(NetworkRunner runner, PlayerRef player)
{
Vector3 spawnPosition = Vector3.up * 2;
NetworkObject networkPlayerObject = runner.Spawn(playerPrefab, spawnPosition, Quaternion.identity, player);
playerList.Add(player, networkPlayerObject);
}
public void OnPlayerLeft(NetworkRunner runner, PlayerRef player)
{
if (playerList.TryGetValue(player, out NetworkObject networkObject))
{
runner.Despawn(networkObject);
playerList.Remove(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) { }
public void OnHostMigration(NetworkRunner runner, HostMigrationToken hostMigrationToken) { }
}
PlayerController.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
}
專案Github
有需要的朋友可以在這裡看到本次教學的專案喔!
OperationException: Plugin Mismatch requested=’FusionPlugin’ got=’Default’ (ErrorCode: 32751)
版本有正確嗎,必須是2020以上的才可以使用