Unity5.1 新的網路引擎UNET(三) UNET NetworkManager
孫廣東 2015.7.12
直接繼承自 MonoBehaviour, 還有就是被設計成了單例 singleton
NetworkManager 網路管理器是一個方便的HLAPI 類,用於管理網路系統 。
對於簡單的網路應用NetworkManager 網路管理器可以使用HLAPI控制 。它提供了簡單的方法來 啟動和停止 客戶端和伺服器,以及 管理場景,而且具有虛擬函式,使用者程式碼可以使用 實現 網路事件的處理程式。NetworkManager 網路管理器一次處理一個客戶端。下面的示例演示一個最小的網路設定。
using UnityEngine.Networking; public class Manager : NetworkManager { public override void OnServerConnect(NetworkConnection conn) { Debug.Log ("OnPlayerConnected"); } }
NetworkManager 網路管理器是 管理網路狀態的多人遊戲的一個組成部分。它實際上被實現完全使用 HLAPI,所以它做的一切都是可被其他forms的開發人員使用的。然而網路管理器包裝了很多有用的功能,使得建立、 執行和除錯儘可能簡單的多人遊戲。
網路管理器可以使用完全不用指令碼。它有在編輯器中有 inspector 控制元件,允許配置其所有功能,和 NetworkManagerHUD 提供簡單、預設的使用者介面,可以在執行時允許被使用者控制的網路遊戲。為高階的使用,開發人員可以從網路管理器派生出類 並通過重寫虛擬函式,為它提供的任何自定義其行為。
網路管理器的功能包括:
• Game State Management
• Spawning Management
• Scene Management
• Debugging Information
• Matchmaking 匹配系統
• Customization 可定製
入門 NetworkManager
網路管理器可以作為控制組件的多人遊戲的核心。若要開始,在你開始的場景,建立一個空的遊戲物件或挑選一個方便管理器物件。從Network/NetworkManager選單項,然後新增NetworkManager元件。新新增的NetworkManager應如所示:
在編輯器中的NetworkManager的的inspector 面板上 允許您配置和控制與網路相關的很多東西。
NetworkManagerHUD 是與NetworkManager相關的的另一個元件。遊戲執行控制網路狀態時,它給你一個簡單的使用者介面。這是很好的入門知識網路專案,但不能用作遊戲最終的 ui 設計。NetworkManagerHUD 看起來像:
真正的遊戲會有正確的UI ,用於控制遊戲狀態 和 允許玩家選擇什麼樣的遊戲 。但是,若要開始,我們可以暫時以此來控制遊戲。
Game State Management
作為客戶端,作為一個專用的伺服器,或作為 “Host” 是客戶端和伺服器在同一時間具備 ,UNet 多人遊戲可以在三種模式下-執行。UNet 旨在使相同的遊戲 程式碼和資產 在所有這些情況下工作。發展為 單人遊戲版本遊戲和 多人遊戲版本遊戲 應該是同一件事。
網路管理器 具有用於輸入每一種模式的方法。NetworkManager.StartClient()、 NetworkManager.StartServer() 和 NetworkManager.StartHost() 是所有可用的指令碼程式碼,所以它們可以被呼叫,從鍵盤輸入的處理程式或自定義UI 事件 。可以選擇要顯示的預設執行時控制元件也呼叫這些相同的功能。也有按鈕在 NetworkManagerHUD 的 inspector上,在Play 模式時呼叫同一函式:
無論哪種方法用來 改變遊戲狀態、 networkAddress網路地址和 networkPort網路埠 屬性被 使用。當啟動時後的伺服器 或主機 時,networkPort 成為 偵聽埠。當客戶端啟動時,networkAddress是要連線到的地址、networkPort 是要連線到的埠。
Spawning Management
網路管理器可以用於管理網路物件從預置的例項化 。大多數遊戲都有 prefab 用作player 的物件,因此網路管理器有一個 槽(欄位),拖動player prefab進行賦值。當一個player prefab 設定時,player 物件會自動產生從該prefab, 為每個使用者在遊戲中建立。這適用於在本地player託管hosted伺服器上,和遠端客戶端上的遠端players 參與者。請注意player prefab 必須有 NetworkIdentity 元件。
除了player prefab,其他物件的預置將動態地被生成了但是必須是ClientScene登 記的。這可以通過使用 ClientScene.RegisterPrefab() 函式,或者它可以由網路管理器自動完成。新增 預置生成列表 會使他們自動註冊。NetworkManager的 inspector 的欄位 配置看起來像:
一旦設定了一個player prefab ,你應該能夠作為主機開始遊戲,看到 player 物件產生。停止這場比賽應該使player 物件被銷燬。當要執行另一個副本的遊戲和 連線到本地主機的客戶端應使另一個player 物件出現,並停止該客戶端應該使該客戶端player 物件被銷燬。
player object 被被生成是由 NetworkManager.OnServerAddPlayer 預設實現。 如果你想自定義 player object 的建立的方式,你可以重寫的虛擬函式。預設實現是類似:
public virtual void OnServerAddPlayer(NetworkConnection conn, short playerControllerId)
{
var player = (GameObject)GameObject.Instantiate(playerPrefab, playerSpawnPos, Quaternion.identity);
NetworkServer.AddPlayerForConnection(conn, player, playerControllerId);
}
請注意,新建立player object.時NetworkServer.AddPlayerForConnection() 必須被呼叫函式,所以它是被生成和與客戶端的連線相關聯。這將產生的物件,所以 NetworkServer.Spawn 不需要為 player object.
Start Positions
若要控制players 被建立,在這裡,你可以使用 NetworkStartPosition 元件。網路管理器查詢場景中的 NetworkStartPosition 物件,如果它找到了,然後它將產生Player的位置和方向 。自定義程式碼可以通過NetworkManager.startPositions列表 ,訪問可用的 NetworkStartPositions,也是一個 helper 函式 GetStartPosition() 對網路管理器,可以在執行 OnServerAddPlayer 用於查詢起始位置。
Scene Management
大多數遊戲都有多個場景。在至少有通常是標題螢幕 或 開始選單場景 還有玩這個遊戲的場景。網路管理器是設定來自動管理場景狀態 和 場景切換 適合多人遊戲的方式。網路管理器的屬性面板 有兩個插槽: offlineScene 和 onlineScene。將 場景物件拖放到這些插槽 啟用網路場景管理。
伺服器或主機啟動時,將載入online線上的場景。這將會成為當前的網路場景。連線到該伺服器的任何客戶端將奉命載入這個場景。這個場景的名稱儲存在 networkSceneName 屬性中。
當網路停止時,通過停止的伺服器或主機,或斷開連線,客戶端將載入offline離線的場景。斷開多人遊戲時遊戲允許自動返回到選單場景 。
通過呼叫 NetworkManager.ServerChangeScene(),遊戲處於活動狀態時,還可以更改場景。這將使所有當前連線的客戶端更改場景,並將更新 networkSceneName,新客戶還將載入新的場景。
雖然網路的場景管理處於活動狀態,呼叫任何遊戲狀態管理功能 NetworkManager.StartHost() 或 NetworkManager.StopClient() 可導致場景變化。這適用於執行時控制 UI。所以通過設定場景 並呼叫這些函式很容易控制流的多人遊戲。
注意,場景變化導致的所有物件在場景將被銷燬。這可能包括網路管理器! 如果你想要網路管理器在轉換是不被銷燬,那就確保 “Dont Destroy On Load” 屬性被設定為 true。在簡單的情況下,這是最佳配置。但是,它是可能有網路管理器在每個使用不同的設定,以控制增量的預製載入或不同的場景切換的場景。
Debugging Information
NetworkManagerHUD 屬性面板在執行時顯示有關網路狀態的其他資訊。這包括:
• 網路連線
• 啟用 NetworkIdentity 伺服器物件
• 啟用 NetworkIdentity 客戶端物件
• client peers
另外,預覽 視窗中顯示所註冊的客戶端訊息處理程式。
Matchmaking匹配系統
網路管理器在執行時 使用者介面和網路管理 inspector UI 允許與匹配服務的互動。NetworkManager.StartMatchmaker() 函式作為匹配介面,並填充具有一個 NetworkMatch 物件的 NetworkManager.matchmaker 屬性。一旦這是啟用的預設 Ui 使用它和 回撥函式對網路管理器讓您執行簡單配對。
有虛擬派生類的網路管理器的函式 可以使用自定義的 respoding 給matchmaker回撥的行為。
Customization自定義
網路管理器的派生類上的虛擬函式可以使用自定義行為。當執行這些職能時,一定要照顧的預設實現提供的功能。 例如,在 OnServerAddPlayer(),NetworkServer.AddPlayer 函式必須呼叫到啟用的Player物件連線。
在Server/Host上呼叫的函式:
// called when a client connects
public virtual void OnServerConnect(NetworkConnection conn);
// called when a client disconnects
public virtual void OnServerDisconnect(NetworkConnection conn)
{
NetworkServer.DestroyPlayersForConnection(conn);
}
// called when a client is ready
public virtual void OnServerReady(NetworkConnection conn)
{
NetworkServer.SetClientReady(conn);
}
// called when a new player is added for a client
public virtual void OnServerAddPlayer(NetworkConnection conn, short playerControllerId)
{
var player = (GameObject)GameObject.Instantiate(playerPrefab, playerSpawnPos, Quaternion.identity);
NetworkServer.AddPlayer(conn, player, playerControllerId);
}
// called when a player is removed for a client
public virtual void OnServerRemovePlayer(NetworkConnection conn, short playerControllerId)
{
UPlayer player;
if (conn.GetPlayer(playerControllerId, out player))
{
if (player.NetworkIdentity != null && player.NetworkIdentity.gameObject != null)
NetworkServer.Destroy(player.NetworkIdentity.gameObject);
}
}
// called when a network error occurs
public virtual void OnServerError(NetworkConnection conn, int errorCode);
在客戶端呼叫的函式 :
// called when connected to a server
public virtual void OnClientConnect(NetworkConnection conn)
{
ClientScene.Ready(conn);
ClientScene.AddPlayer(0);
}
// called when disconnected from a server
public virtual void OnClientDisconnect(NetworkConnection conn)
{
StopClient();
}
// called when a network error occurs
public virtual void OnClientError(NetworkConnection conn, int errorCode);
// called when told to be not-ready by a server
public virtual void OnClientNotReady(NetworkConnection conn);
匹配時呼叫的函式:
// called when a match is created
public virtual void OnMatchCreate(CreateMatchResponse matchInfo)
// called when a list of matches is received
public virtual void OnMatchList(ListMatchResponse matchList)
// called when a match is joined
public void OnMatchJoined(JoinMatchResponse matchInfo)
inspector