主題

【Unity x Photon】練習做多人遊戲,Photon學習筆記 與 RPC

趴趴鼠Loading | 2021-03-23 04:52:19 | 巴幣 132 | 人氣 292

最近花個幾天學習Photon。
最終跟著這個系列做出一個多人專案,因為成品跟影片中的一模一樣,所以直接放最後一集看成果:

還有另一系列的教學影片,但我覺得它的程式架構有點冗長。


多人插件大概分為Mirror和Photon。
Mirror開源且完全免費,官方還聲稱適合製作MMORPG規模,但官方沒提供Host,所以要自己架主機。
Photon提供免費20人同時在線的額度。


以下是這次學習的筆記,更多可以直接看Notion的。

透過網路產生物件:
  • 都要放在Resources 資料夾。(原因是沒有被關聯的資料就不會被包含在Build,而Resources資料夾內的資料都會被包含。)
  • 不能用editor 指定該prefab,要用Resources.load(string path....)讀取
  • 要產生掛有Photon View物件的物件也必須掛有Photon View。
  • View id不可重複。

遊戲架構: (取自參考的系列影片)
上面有提到,要用PhotonNetwork.Instantiate()來產生物件的父物件必須也掛有PhotonView,所以RoomManager、PlayerManager和PlayerController都掛有PhotonView。

玩家從大廳房間進入到遊戲時由RoomManager產生PlayerManager,由PlayerManager再產生玩家可以操縱的角色,並負責玩家死亡、重生等事宜。雖然兩者都是同個玩家擁有,但ViewID各不同。


切換裝備:
遊戲內玩家各有2把武器可以切換,兩把槍都掛有PhotonView(我不確定掛PhotonView的基準是什麼,我猜是要同步Transform資訊的物件就要掛)。
切換裝備時將武器index包在photon的hashtable型態,再修改OnPlayerPropertiesUpdate方法去處理。


if (!pv.IsMine && targetPlayer == pv.Owner)這句話我想了好久才想通一點。
  • !pv.IsMine:自己local的視角是已經切換武器的了,所以自己不需要再接收廣播資料。
  • targetPlayer :誰切換了武器。
  • pv.Owner:Player類別,回傳local的玩家物件。
意即: 其他除了自己之外的玩家畫面裡的"我"的物件都執行切換武器的動作。


RPC(遠端程序呼叫):
爬了一堆文其實我也不太懂XD。

《在分散式計算,遠端程序呼叫(英語:Remote Procedure Call,縮寫為 RPC)是一個電腦通信協定。該協定允許執行於一台電腦的程式呼叫另一個位址空間(通常為一個開放網路的一台電腦)的子程式,而程式設計師就像呼叫本地程式一樣,無需額外地為這個互動作用編程(無需關注細節)。RPC是一種伺服器-客戶端(Client/Server)模式,經典實現是一個通過傳送請求-接受回應進行資訊互動的系統。》()

簡單的理解是: 一個協定,使工程師在使用遠端方法就像使用本地方法一樣輕鬆(底層都做了複雜的工作)。

武器Shoot方法:

pv.RPC("RPC_Shoot", RpcTarget.All, hit.point, hit.normal);
透過RPC呼叫所有玩家執行本地的"RPC_Shoot"方法。 我實驗一下發現是各自執行local的方法,而不是執行呼叫該RPC訊息的玩家的方法。

再來是玩家接受傷害:
當下懷疑既然只有被打的A才會繼續執行扣血的動作,那為什麼還要透過RPC告訴大家? 原因是透過RPC更新所有玩家端的玩家A血量。意即:若場上有3個玩家,則就有3個玩家A的分身,透過RPC叫每個人電腦裡面的玩家A去執行扣血的動作。

最後死亡由PlayerManager進行回收,並在產生player時順便告訴player產生它的manager是誰。


RPC or CustomProperties?
打到這裡剛好萌生個問題,要同步玩家的資料,應該使用RPC還是CustomProperties?
讀了一下這串的留言大致整理(我好想睡了...):

PhotonView:
  1. 頻繁同步GameObject狀態的物件。

RPC
  1. 適用於針對特定對象的方法。
  2. 小心cache 爆棚。
  3. 範例:對話、攻擊、傷害
CustomProperties
  1. 適用於低更新頻率的資料。
  2. 礙於傳輸資料長度,常將一個字母簡化成2個英文字,即訊息別傳太多。
  3. 範例: 切換武器、凸顯某物品、倒數計時
結論是大致都能做到相同的效果,只差在傳輸效能上(?



待閱讀清單:
[RPC]

創作回應

教授加博士先生
辦Steam開發者帳號 繳money(好像3000台幣)每款遊戲 就可以拿到一個AppID 有那ㄍAppID 你就可以各種無線白嫖他的relay serverㄌ 自己測試架連線多人遊戲等
2021-03-24 01:38:22
教授加博士先生
遊戲其實也不會綁死啦 一般你要多平台發售 你寫code就要用Interface想好哪些該抽象化獨立出來 像是[Rpc]概念也只是"送消息給遠端的人執行特定函數" 一個很高層的概念 底層怎樣送這個消息 完全是看你想要搞哪個平台 Mirror其實就是只有做完上層 底下有一層Interface 可以插拔 Steam/Telepathy/ XXX等 底下實際傳輸層(Transport Layer)你可以自己換來換ㄑ 所以code也不會說被綁死在哪拉
2021-03-24 01:42:14
教授加博士先生
不過還是建議先Photonㄅ Mirror我覺得對剛寫網路的人不友善 很多坑有很多BUG (Unity社群因為UNET被廢 一些開發者自己搞出來ㄉ社群產物)
2021-03-24 01:47:13
感謝大大的無私分享
Mirror 現在蠻積極更新的 Discord 社群上面也蠻活躍的 不過我覺得羊毛出在羊身上 伺服器的錢遲早還是要花
Photon 最大的好處在於完全不用煩惱 NAT Traversal 的問題,這方面都交給 Photon 處理
但是 Mirror 變成會需要仰賴第三方,像是 Steam 或 PlayFab
2021-03-24 22:08:54
趴趴鼠Loading
感謝分享! 第一次聽到PlayFab,微軟的東西感覺就很貴[e15]
2021-03-25 02:21:01
朱朱
作者加油,我有寫過python
2021-04-23 02:15:17

更多創作