這部分介紹了如何添加處理不同級別加載的功能产舞,該功能基于目前房間中的玩家數(shù)量驳癌。
主要內(nèi)容
- 加載Arena Routine
- 觀察玩家連接
- 從大廳加載Arena
加載Arena Routine
我們創(chuàng)造了4個不同的房間盼砍,并且按照約定命名他們,最后一個字符是玩家的數(shù)量寺擂,所以現(xiàn)在很容易綁定當前房間和關(guān)聯(lián)場景球員數(shù)量球涛。這是一種被稱為“convention over configuration”的非常有效的技術(shù)杀迹,基于“Configuration”的方法亡脸,舉例來說,關(guān)于房間中給定數(shù)量的玩家佛南,已經(jīng)維護了一個場景名字查找表梗掰。我們的腳本然后會查看該列表嵌言,并返回一個無關(guān)的場景嗅回。 “Configuration”一般需要更多的代碼,這就是為什么我們將在這里使用“Convention”摧茴,讓我們更容易實現(xiàn)想要的功能绵载,而不會讓無關(guān)的功能污染我們的代碼。
打開GameManager腳本
-
在private methods區(qū)塊內(nèi)添加一個新方法苛白,不要忘記保存
#region Private Methods void LoadArena() { if (!PhotonNetwork.isMasterClient) { Debug.LogError("PhotonNetwork : Trying to Load a level but we are not the master Client"); } Debug.Log("PhotonNetwork : Loading Level : " + PhotonNetwork.room.playerCount); PhotonNetwork.LoadLevel("Room for " + PhotonNetwork.room.playerCount); } #endregion
保存GameManager腳本
當我們調(diào)用這個方法時娃豹,我們將根據(jù)我們所在的房間的playerCount屬性加載適當?shù)姆块g。
在這里有兩件事要注意购裙,這是非常重要的懂版。
- 如果我們是master,PhotonNetwork.LoadLevel()才應該被調(diào)用。所以我們使用PhotonNetwork.isMasterClient首先檢查是否是master躏率。檢查這一點是調(diào)用者的責任躯畴,我們將在本節(jié)的下一部分中介紹。
- 我們使用PhotonNetwork.LoadLevel()加載我們想要的級別薇芝,我們不直接使用Unity蓬抄,因為我們想依靠Photon加載這個級別,使在房間中所有連接的客戶端都生效夯到,因為我們在這個游戲中啟用了PhotonNetwork.automaticallySyncScene嚷缭。
現(xiàn)在我們可以加載正確的級別,讓我們綁定到玩家的連接和斷開上面。
觀察玩家連接
目前阅爽,我們的GameManager腳本是一個常規(guī)的MonoBehaviour路幸,我們在前面的教程中學習了使用Photon回調(diào)的各種方法,現(xiàn)在GameManager需要監(jiān)聽玩家的連接和斷開連接付翁。讓我們實現(xiàn)這個劝赔。
打開GameManager腳本
-
把當前的基類MonoBehaviour修改為Photon.PunBehaviour
public class GameManager : Photon.PunBehaviour {
-
添加下面的Photon回調(diào)信息
public override void OnPhotonPlayerConnected(PhotonPlayer other) { Debug.Log("OnPhotonPlayerConnected() " + other.name); // not seen if you're the player connecting if (PhotonNetwork.isMasterClient) { Debug.Log("OnPhotonPlayerConnected isMasterClient " + PhotonNetwork.isMasterClient); // called before OnPhotonPlayerDisconnected LoadArena(); } } public override void OnPhotonPlayerDisconnected(PhotonPlayer other) { Debug.Log("OnPhotonPlayerDisconnected() " + other.name); // seen when other disconnects if (PhotonNetwork.isMasterClient) { Debug.Log("OnPhotonPlayerConnected isMasterClient " + PhotonNetwork.isMasterClient); // called before OnPhotonPlayerDisconnected LoadArena(); } }
保存GameManager腳本
現(xiàn)在,我們有了一個完整的設(shè)置胆敞。每當玩家加入或離開房間時着帽,我們都會被通知,我們將調(diào)用我們剛才創(chuàng)建的LoadArena()方法移层。但是仍翰,只有當我們是PhotonNetwork.isMasterClient的情況下,我們才調(diào)用LoadArena()观话。
讓我們現(xiàn)在回到Lobby予借,最終加入房間的時候能夠加載正確的場景。
從大廳加載Arena
編輯腳本Launcher
-
把下面的腳本添加到OnJoinedRoom方法
// #Critical: We only load if we are the first player, else we rely on PhotonNetwork.automaticallySyncScene to sync our instance scene. if (PhotonNetwork.room.playerCount == 1) { Debug.Log("We load the 'Room for 1' "); // #Critical // Load the Room Level. PhotonNetwork.LoadLevel("Room for 1"); }
保存腳本
讓我們測試一下频蛔,打開Launcher場景灵迫,運行它。點擊“play”晦溪,讓系統(tǒng)連接并加入一個房間瀑粥。就這樣,Lobby沒有問題三圆。但如果你離開房間狞换,你會注意到,當回到大廳時舟肉,它會自動重新加入房間修噪。噢,讓我們解決一下這個問題路媚。
如果你還不知道為什么黄琼,簡單地分析一下日志。我只是簡單地說說一下整慎,因為這需要實踐和經(jīng)驗來解決這個問題脏款,知道問題出在哪里以及如何調(diào)試它。
你自己嘗試一下院领,如果你仍然找不到問題的根源弛矛,讓我們一起做。
- 運行Launcher場景
- 點擊Play按鈕比然,等到你加入了一個房間丈氓,"Room for 1"加載完畢
- 清空Unity Console
- 點擊“Leave Room”
- 研究一下Unity Console,注意記錄中有這句話 "DemoAnimator/Launcher: OnConnectedToMaster() was called by PUN"
- 停止Launcher場景
- 再Unity Console中雙擊這句話 "DemoAnimator/Launcher: OnConnectedToMaster() was called by PUN",會打開腳本并指向調(diào)用的那一行
- 嗯...每次我們連接上的時候万俗,都會自動的加入一個房間JoinRandomRoom湾笛,但是這并不是我們想要的。
要解決這個問題闰歪,我們需要知道上下文嚎研。當用戶點擊“Play”按鈕時,我們應該記下一個標志库倘,以便知道連接過程源于用戶临扮。然后我們可以在各種Photon回調(diào)中,檢查這個標志教翩,執(zhí)行相應代碼杆勇。
編輯Launcher腳本
-
在Private Variables部分創(chuàng)建一個新的屬性
/// <summary> /// Keep track of the current process. Since connection is asynchronous and is based on several callbacks from Photon, /// we need to keep track of this to properly adjust the behavior when we receive call back by Photon. /// Typically this is used for the OnConnectedToMaster() callback. /// </summary> bool isConnecting;
-
在connect()方法開頭加入下面代碼
// keep track of the will to join a room, because when we come back from the game we will get a callback that we are connected, so we need to know what to do then isConnecting = true;
-
在OnConnectedMaster()方法中,在PhotonNetwork.JoinRandomRoom()外面加一個if語句
// we don't want to do anything if we are not attempting to join a room. // this case where isConnecting is false is typically when you lost or quit the game, when this level is loaded, OnConnectedToMaster will be called, in that case // we don't want to do anything. if (isConnecting) { // #Critical: The first we try to do is to join a potential existing room. If there is, good, else, we'll be called back with OnPhotonRandomJoinFailed() PhotonNetwork.JoinRandomRoom(); }
保存腳本
現(xiàn)在饱亿,如果我們再次測試并運行啟動場景蚜退,并在大廳和游戲之間來回切換,一切都很好:)為了測試場景的自動同步彪笼,您需要發(fā)布應用程序(發(fā)布桌面钻注,它運行測試最快),并在Unity之外運行它配猫,所以你有了兩個玩家幅恋,將連接和加入一個房間。 如果Unity Editor首先創(chuàng)建房間章姓,它將是MasterClient佳遣,您將能夠在Unity控制臺中驗證您在連接時獲得“PhotonNetwork:Loading Level:1”和更高版本“PhotonNetwork:Loading Level:2” 發(fā)布的實例识埋。
好凡伊!我們已經(jīng)講了很多,但這只是工作的一半... :)我們將在下一節(jié)需要解決玩家本身問題窒舟。不要忘記休息系忙,以更有效地吸收所解釋的各種概念。
如果您對某個功能有疑問惠豺,或者您在閱讀本教程后遇到問題银还,并遇到錯誤或未在此處提及的問題,歡迎在論壇上提出問題洁墙,我們將竭誠為您服務(wù):)
原文
http://doc.photonengine.com/en-us/pun/current/tutorials/pun-basics-tutorial/gamemanager-levels