多人插件大概分為Mirror和Photon。
- 都要放在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:
- 頻繁同步GameObject狀態的物件。
RPC
- 適用於針對特定對象的方法。
- 小心cache 爆棚。
- 範例:對話、攻擊、傷害
CustomProperties
- 適用於低更新頻率的資料。
- 礙於傳輸資料長度,常將一個字母簡化成2個英文字,即訊息別傳太多。
- 範例: 切換武器、凸顯某物品、倒數計時
結論是大致都能做到相同的效果,只差在傳輸效能上(?