【程序】必看乾貨:Photon多人遊戲開發教程

PUN介紹後端

 

http://vibrantlink.com/緩存

 

入門服務器

Photon Unity Networking(首字母縮寫PUN)是一個Unity多人遊戲插件包。它提供了身份驗證選項、匹配,以及快速、可靠的經過咱們的Photon後端實現的遊戲內通訊。網絡

PUN輸出幾乎全部Unity支持的平臺,且有兩種選項:app

注意:對於Unity 5,兩個PUN插件包都含相同的文件。你能夠買PUN+ 來得到60個月的100 CCU,但客戶端上仍使用PUN Free。負載均衡

PUN、PUN+和UNet的對比dom

詳見文章Photon Unity Networking (PUN) Compared To Unity Networking (UN)來查看二者比較的細節。ide

一些必須的代碼函數

要充分使用PUN,你將須要寫一些腳本。本頁向你展現入門的最重要部分。插件

你也應該花一些時間來經過Marco Polo Tutorial。

鏈接

上面的代碼是你須要鏈接並開始使用Photon功能的全部代碼。

ConnectUsingSettings 設置你的客戶端的遊戲版本並使用一個由PUN設置嚮導寫入的配置文件,該配置文件保存在PhotonServerSettings裏面。

匹配

接下來,你想加入現有的房間或建立本身的。下面的代碼顯示了啓動或加入遊戲的可能方法調用。

好朋友經常想要一塊兒玩遊戲。若是他們能夠交流(例如 使用Photon Chat, Facebook), 他們能夠瞎編一個房間名並使用JoinOrCreateRoom方法。由於他們知道房間的名字,他們能夠建立爲他人不可見,像這樣:

C#代碼示例:

使用 JoinOrCreateRoom方法,若是房間不存在就會建立該房間。若是房間滿了, OnPhotonJoinRoomFailed會被調用 (若是你在某個地方實現了這個回調函數)。

遊戲

GameObjects能夠被實例化爲"networked GameObjects"。它們會有一個能夠被識別的PhotonView組件和一個全部者(或控制者)。全部者會更新其餘人。持續更新能夠經過拖拽一個腳本到一個PhotonView的 Observed字段被髮送。須要更新的腳本必須實現OnPhotonSerializeView像這樣:

客戶端能夠爲不見用的操做執行Remote Procedure Calls:

獨立於GameObjects, 你也能夠發送你本身的事件:

初始設置

Photon Unity Networking (PUN)真的很容易設置。把PUN導入到一個新的項目中,而後PUN設置嚮導就會彈出來,如圖0-1所示。經過輸入一個郵箱地址來註冊一個新的(免費) Photon Cloud賬號,或者複製粘貼一個已有的AppId到該字段裏。打完收工。

若是你想要本身託管一個Photon服務器,點擊"skip",而後像以下描述的那樣編輯 PhotonServerSettings。

圖 0-1 PUN設置嚮導

要鏈接,你只需在你的代碼中調用PhotonNetwork.ConnectUsingSettings()。若是你須要更多的控制,詳見下面的 Connect Manually。

Photon服務器設置

設置嚮導會添加一個PhotonServerSettings文件到你的項目,用來保存配置。如圖0-2所示,這也是去編輯服務器設置的地方。

圖 0-2 PhotonServerSetting文件屬性

你能夠設置AppId、Photon Cloud Region和更多的。你的客戶端的Game Version是在代碼裏被設置的。

要選擇的最重要的選項是託管類型。

託管類型

經過Hosting Type你選擇處理你遊戲的服務器和其餘配置。

Photon Cloud和Best Region都涉及到咱們管理的雲服務。您能夠選擇特定區域,也可讓客戶選擇最佳ping區域。

若是你想在別的地方運行Photon服務器,選擇Self Hosted。安裝程序以下。

或者,你的客戶能夠在脫機模式。

最佳託管區域

最佳區域模式將在應用首次啓動的時候ping全部已知區域。因爲這須要一點時間,結果被存儲在PlayerPrefs。這會加快鏈接時間。

你能夠設置哪些區域能夠忽略。在更少的區域分發客戶端會致使剩餘區域的玩家更多。這在遊戲流行以前是有益的。

使用PhotonNetwork.OverrideBestCloudServer()來定義要使用的另外一個區域。

自託管

若是你爲iOS開發遊戲能夠考慮閱讀 PUN and IPv6和how to setup Photon Server for IPv6。

若是你要本身託管一個Photon服務器,你應在PhotonServerSettings裏面設置好它的地址和端口。當這些都被正確設置了,你能夠在你的代碼裏調用PhotonNetwork.ConnectUsingSettings()。

確保您的客戶端能夠到達輸入的地址。它能夠是一個公共的、靜態的IP地址、主機名或在你的客戶端也使用的網絡中的任何地址。

端口取決於所選協議,因此請確保這兩個字段匹配。清除該字段會將其重置爲默認端口。

協議

這裏默認是(可靠的)UDP,但Photon還支持使用TCP以及將容許一個可靠的HTTP協議。

咱們建議你堅持UDP。PUN+不支持TCP。WebGL導出只能使用WebSockets。

客戶端設置

客戶端設置部分包含了每一個項目應設置的幾個選項。

當你勾選Auto-Join Lobby時,PUN將在鏈接(或離開房間)時自動加入默認大廳。Photon的大廳提供當前房間的列表,這樣玩家能夠選擇一個加入。這個默認是關閉的,由於更好的選擇是使用隨機匹配,就像全部的演示案例中使用的那樣。

啓用Enable Lobby Stats來從服務器獲取大廳統計信息。若是遊戲使用多個大廳,而且你想要向玩家展現每個活動,則這個統計信息會頗有用。每一個大廳,你均可以獲取這些屬性: name、type、room和playercount。詳見PhotonNetworking.LobbyStatistics!

這些設置在PUN v1.60版本引入。

遠程過程調用列表

Remote Procedure Calls使你能夠在一個房間裏調用全部客戶端上的方法。PUN 將這些方法的列表保存在PhotonServerSettings。對於最初的設置,這是不相關的。詳見Remote Procedure Calls。

手動鏈接

做爲替代自動鏈接的PhotonNetwork.ConnectUsingSettings()方法你能夠經過PhotonNetwork.ConnectToMaster()方法來手動鏈接你本身的Photon服務器。當你託管付費Photon服務器時這是有用的。

對於ConnectToMaster(),你須要提供一個masterServerAddress和一個port參數。地址能夠是你的On-Premises DNS名稱或一個IP。它能夠包括冒號後的端口(而後傳遞0做爲端口)或您能夠單獨經過端口。

ConnectToMaster()方法有更多的另外兩個參數 : "appID"和"gameVersion"。二者都只與Photon Cloud有關,而且當你本身託管Photon服務器時,能夠設置爲任何值。

對於Photon Cloud, 使用ConnectUsingSettings()方法。它涉及到咱們的Name Server自動找到一個區域的主服務器。

功能概述

內容提要

· PUN插件

· 鏈接和主服務器

· 版本控制

· 建立和加入遊戲

· MonoBehaviour回調函數

· 在遊戲房間裏發送消息

· Photon視圖組件

· 觀察Transform

· 觀察MonoBehaviour

· 遠程過程調用

· RPCs和加載關卡的時機

PUN

當你導入PUN時,設置嚮導窗口會彈出來。如何設置請看導入PUN與設置小節。

PUN由至關多的文件組成, 然而只有一個是真正重要的: PhotonNetwork。這個類包含全部須要的函數和變量.。若是您有自定義要求,能夠隨時修改源文件。

要從Unity中使用PUN,你須要把 "PhotonNetwork"和"Utilitys" 文件夾移動到AssetsPlugins文件夾。

爲了告訴你這個API如何工做,這裏有幾個例子。

回到內容提要

鏈接

PhotonNetwork始終使用主服務器和一個或多個遊戲服務器。主服務器管理當前可用的遊戲並進行匹配。一旦房間被發現或建立,實際的遊戲是在遊戲服務器上完成的。

全部的服務器都運行在專用的機器上,沒有所謂的玩家託管的服務器。你沒必要費心記住該服務器組織,PUN會爲你處理它。

C#代碼示例:

上面的代碼是你須要鏈接並開始使用Photon功能的全部代碼。ConnectUsingSettings 設置你的客戶端的遊戲版本並使用一個由PUN設置嚮導寫入的配置文件,該配置文件保存在PhotonServerSettings裏面。你也能夠修改文件PhotonServerSettings 屬性來鏈接到你本身的服務器。或者,使用Connect()方法來忽略該PhotonServerSettings 文件。

版本控制

Photon的負載均衡邏輯使用你的AppId來區分你的和他人的遊戲。玩家也會被遊戲版本分開,ConnectUsingSettings的參數(見上文)。經過這種方式,您能夠發佈新功能的客戶端,而不破壞舊版本的遊戲。

因爲咱們不能保證不一樣PUN的版本之間相互兼容,PUN把它本身的版本號添加到你的遊戲裏。更新PUN可能會從舊的版本中分離出新的客戶端,但不會打破老客戶端。

建立和加入遊戲

接下來,你想加入或建立一個房間。下面的代碼展現了一些必要的函數:

在最好的狀況下,您的遊戲使用隨機配對。JoinRandomRoom()將嘗試加入任何房間。若是該方法失敗了(沒有房間接受另外一個玩家),只需建立一個新的房間,並等到其餘玩家隨機加入它爲止。

或者,您的客戶端能夠得到當前可用的房間列表。這是經過加入一個大廳來得到的。

大廳自動發送他們的房間列表到客戶端,並在時間間隔內更新(從而減小流量)。玩家不會看到對方,且沒法溝通(以防止當您的遊戲繁忙時出問題)。

PhotonNetwork插件能夠在其鏈接時自動加入默認大廳。把PhotonServerSettings文件裏的"Auto-Join Lobby"屬性開啓便可。

當你的客戶端在一個大廳裏時,房間列表會獲得更新, 這些更新會緩存。若是須要的話,你能夠經過GetRoomList方法來每一幀訪問房間列表。

C#代碼示例:

關於匹配的更多信息請參考Matchmaking And Room Properties。

回調函數

PhotonNetwork使用多個回調函數來讓你的遊戲知道狀態的變化,如「已鏈接」或「已加入一個遊戲」。像往常對Unity同樣,回調可在任何腳本里實現。

若是你的腳本擴展Photon.PunBehaviour, 你能夠單獨重寫每一個回調。在這種狀況下,您沒必要調用基類實現。

C#代碼示例:

你不須要擴展PunBehaviour。若是你在其自己身上實現它全部的回調函數也會起做用。它們也在枚舉PhotonNetworkingMessage中被列出和描述。

這包括創建遊戲房間的基礎知識。接下來是遊戲中的實際交流。

發消息

在一個房間裏,你能夠發送網絡信息給其餘鏈接的玩家。此外,您還能夠發送緩衝消息,也將被髮送到將來鏈接的玩家(以玩家生成爲例)。

發送消息可使用兩種方法。不管是RPCs,仍是經過在一個由PhotonView觀察的腳本里實現OnSerializePhotonView。

然而有更多的網絡互動。你能夠監聽一些網絡事件的回調函數,如OnPhotonInstantiate或OnPhotonPlayerConnected,而且你能夠觸發其中一些事件,如 PhotonNetwork.Instantiate。若是你被最後一段弄糊塗了,不要擔憂,下一步咱們會爲這些主題逐個作解釋。

Photon視覺同步組件

PhotonView是一個用於發送消息(RPCs和OnSerializePhotonView)的腳本組件。你須要將PhotonView依附到遊戲對象或預設上。請注意,PhotonView和Unity的NetworkView很是類似。

整個過程,你的遊戲中須要至少一個PhotonView,才能發送消息和可選的實例化/分配其餘的PhotonViews。

如圖下圖所示,添加一個PhotonView到一個遊戲對象,只需選擇一個遊戲對象並使用: "Components/Miscellaneous/Photon View"。

圖 0-1 Photon Cloud:Photon View

觀察Transform

若是你將一個Transform綁定到PhotonView的觀察屬性上,你能夠選擇同步位置、旋轉和尺度或玩家的這些屬性組合。這能夠極大的幫助製做原型或小遊戲。注意:任何觀察到的值變化將發送全部觀察到的值-而不僅是發生變化的那個單一值。此外,更新的值是不平滑的或插值。

觀察MonoBehaviour

PhotonView能夠被設置來觀察MonoBehaviour。在這種狀況下,腳本的OnPhotonSerializeView方法會被調用。此方法被調用來寫入對象的狀態並讀取它,這取決於腳本是否由本地玩家控制。

下面簡單的代碼展現瞭如何用幾行代碼來增長角色狀態同步:

C#代碼示例:

觀察選項

Observe Option字段讓你選擇更新如何發送以及什麼時候被髮送。該字段還會影響到OnPhotonSerializeView被調用的頻率。

Off 顧名思義,關掉。若是該PhotonView被保留爲RPCs限定時能夠頗有用。

Unreliable 更新如是被髮送,但可能會丟失。這個想法是,下一次更新很快到來,並提供所需的正確的/絕對的值。這對於位置和其餘絕對數據來講是有利的,但對於像切換武器這樣觸發器來講是很差的。當用於同步的遊戲對象的位置,它會老是發送更新,即便該遊戲對象中止運動(這是很差的)。

Unreliable on Change 將檢查每個更新的更改。若是全部值與以前發送的同樣,該更新將做爲可靠的被髮送,而後全部者中止發送更新直到事情再次發生變化。這對於那些可能會中止運動的以及暫時不會建立進一步更新的遊戲對象來講是有利的。例如那些在找到本身的位置後就再也不移動的箱子。

Reliable Delta Compressed 將更新的每一個值與它以前的值進行比較。未更改的值將跳過以保持低流量。接收端只需填入先前更新的值。任何你經過OnPhotonSerializeView寫入的都會自動進行檢查並以這種方式被壓縮。若是沒有改變, OnPhotonSerializeView不會在接收客戶端調用。該「可靠的」部分須要一些開銷,因此對於小的更新,應該考慮這些開銷。

如今開始,以另外一種方式交流:RPCs。

遠程過程調用

Remote Procedure Calls (RPC)使你能夠調用"networked GameObjects"上的方法,對由用戶輸入等觸發的不經常使用動做頗有用。

一個RPC會被在同房間裏的每一個玩家在相同的遊戲對象上被執行,因此你能夠容易地觸發整個場景效果就像你能夠修改某些GameObject。

做爲RPC被調用的方法必須在一個帶PhotonView組件的遊戲對象上。該方法自身必需要被[PunRPC]屬性標記。

要調用該方法,先訪問到目標對象的PhotonView組件。而不是直接調用目標方法,調用PhotonView.RPC()並提供想要調用的方法名稱:

你能夠發送一系列的參數,但它必須匹配該RPC方法的定義。

這些是最基本的。詳情請閱讀Remote Procedure Calls.

時機

RPCs在指定的PhotonViews上被調用,並老是以接收客戶端上的匹配者爲目標。若是一個遠程客戶端尚未加載或建立匹配的PhotonView,這個RPC就會丟失!

所以,丟失RPCs一個典型的緣由就是當客戶端加載新場景的時候。它只須要一個已經加載有新遊戲對象的場景的客戶端,而且其餘客戶端不能理解這個RPC(直到這些客戶端也加載了相同的場景)。

PUN能夠幫你解決此問題。只需在你鏈接以前設置PhotonNetwork.automaticallySyncScene = true並在房間的主客戶端上使用 PhotonNetwork.LoadLevel()。這樣,一個客戶端定義了全部客戶端必須在房間/遊戲中加載的關卡。

客戶端能夠中止執行接收到的消息來防止RPCs丟失(這正是LoadLevel方法幫你作的)。當你獲得一個RPC來加載一些場景,當即設置isMessageQueueRunning = false直到該內容被初始化。

例子:

禁用消息隊列將延遲傳入和傳出消息,直到隊列被解鎖。顯然,當你準備好要繼續的時候,打開隊列是很是重要的。

篇幅有限,請你們點擊原文,下載附件,閱讀完整PDF,另外還有一篇是介紹綜合開發文檔的,敬請期待,謝謝!

相關文章
相關標籤/搜索