日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

项目实训--Unity多人游戏开发(九、PUN2学习记录)

發(fā)布時間:2023/12/18 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 项目实训--Unity多人游戏开发(九、PUN2学习记录) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

文章目錄

    • Photon Unity Networking簡介
    • PUN2基礎(chǔ)&Lobby/Room
    • 玩家昵稱

Photon Unity Networking簡介

Pun2是一個API很簡單的多人游戲開發(fā)框架。
可以通過繼承pun框架提供的類或?qū)崿F(xiàn)其各種接口與unity項目融合實現(xiàn)多人聯(lián)機。
… …

PUN2基礎(chǔ)&Lobby/Room

Unity基礎(chǔ)知識不過多贅述。
從MonoBehaviour中派生出的類,MonoBehaviour本質(zhì)上將我們的類變成了一個Unity組件,然后我們可以將它放到游戲?qū)ο蠡蝾A(yù)設(shè)上。擴展MonoBehaviour的類可以訪問許多非常重要的方法和屬性。比如Start()等回調(diào)函數(shù)。

我們的游戲?qū)⒂幸粋€基于玩家數(shù)量的可調(diào)整大小的房間功能,為了確保加載的場景對于每個連接的玩家都是相同的,我們將利用Photon提供的PhotonNetwork.AutomaticallySyncScene(可見下例代碼)。當(dāng)這個變量為true時,主客戶端可以調(diào)用PhotonNetwork.LoadLevel(),所有連接的玩家都會自動加載相同的關(guān)卡。

PUN對于回調(diào)非常靈活,并且提供了兩種不同的實現(xiàn)(繼承MonoBehaviourPunCallbacks類/單獨實現(xiàn)接口)。為了便于學(xué)習(xí),讓我們涵蓋所有方法,我們將根據(jù)具體情況選擇最適合的方法。其中繼承類是最簡便的一種方法。

新建腳本
編寫連接服務(wù)器方法
添加using Photon.Pun;,代碼如下:

#region Private Fields//版本控制,不同版本的玩家會被隔離開。應(yīng)該是能實現(xiàn)多版本在線,相同版本之間才能匹配,不會出現(xiàn)某個玩家缺少資源而崩潰的情況吧string gameVersion = "1";#endregion#region MonoBehaviour CallBacksvoid Awake(){//自動同步場景,當(dāng)這個變量為真時,主客戶端可以調(diào)用PhotonNetwork.LoadLevel()和所有連接的玩家都會自動加載相同的關(guān)卡。PhotonNetwork.AutomaticallySyncScene = true;}void Start(){Connect();//調(diào)用了下面的一個公共方法}#endregion#region Public Methodspublic void Connect(){if (PhotonNetwork.IsConnected){// #Critical we need at this point to attempt joining a Random Room. If it fails, we'll get notified in OnJoinRandomFailed() and we'll create one.PhotonNetwork.JoinRandomRoom();}else{//連接Photon服務(wù)器PhotonNetwork.ConnectUsingSettings();//使用設(shè)置(服務(wù)器區(qū)域、游戲版本等),見下圖。PhotonNetwork.GameVersion = gameVersion;}}#endregion

修改繼承類以重寫回調(diào)函數(shù) 把MonoBehaviour修改為MonoBehaviourPunCallbacks,這個類既有MonoBehaviour的特性又有各種Pun接口的特性。所以繼承之后再實現(xiàn)接口實際上也是去override回調(diào)方法。
添加命名空間引用 添加using Photon.Pun; using Photon.Realtime;
編寫回調(diào)函數(shù)
寫一個連接到主服務(wù)器的回調(diào)函數(shù)和斷開連接的回調(diào)函數(shù)。對于每一種情況都應(yīng)該實現(xiàn)回調(diào)函數(shù),以做出相應(yīng),增加軟件的5E特性。同時也是良好的人機交互的必要條件。
對于眾多的回調(diào)函數(shù)可以用#region …和#endregion包圍起來,更好的查看代碼。

public override void OnConnectedToMaster() {Debug.Log("PUN Basics Tutorial/Launcher: OnConnectedToMaster() was called by PUN"); }public override void OnDisconnected(DisconnectCause cause) {Debug.LogWarningFormat("PUN Basics Tutorial/Launcher: OnDisconnected() was called by PUN with reason {0}", cause); }

若連接成功則調(diào)用加入房間
現(xiàn)在已經(jīng)知道是否加入到了主服務(wù)器。
如果連接到了服務(wù)器那么就可以開始涉及到大廳與房間了,按照官方教程,大廳暫時不去詳細(xì)的寫。因為還涉及到GUI。下面先試著直接加入房間。

PhotonNetwork.JoinRandomRoom();

房間的回調(diào)
但是如果此時沒有任何一個房間,那么必然會報錯,而且我們也無法得知是否加入房間成功。
因此這里就需要房間相關(guān)的回調(diào)函數(shù)了。

//如果加入房間失敗了--沒有空閑房間--則創(chuàng)建房間,如下代碼使用的默認(rèn)的參數(shù)設(shè)置。 public override void OnJoinRandomFailed(short returnCode, string message) {Debug.Log("PUN Basics Tutorial/Launcher:OnJoinRandomFailed() was called by PUN. No random room available, so we create one.\nCalling: PhotonNetwork.CreateRoom");// #Critical: we failed to join a random room, maybe none exists or they are all full. No worries, we create a new room.PhotonNetwork.CreateRoom(null, new RoomOptions());//創(chuàng)建一個房間并加入 }//加入房間成功的回調(diào)函數(shù) public override void OnJoinedRoom() {Debug.Log("PUN Basics Tutorial/Launcher: OnJoinedRoom() called by PUN. Now this client is in a room.");//成功加入房間了,可以實現(xiàn)別的事情,比如在聊天框中輸出“xxx 加入了房間”等任何需要的事情 }

tips:具體各種可能的狀況后續(xù)編寫應(yīng)對,此處根據(jù)官方文檔進行最關(guān)鍵的回調(diào)方法進行學(xué)習(xí)。


暴露私有變量到unity的inspector面板
在變量上方加上標(biāo)簽:[SerializeField]。
有些變量通過代碼來編寫其值可能不會特別方便或者有時候更合適inspector面板里手動去設(shè)置其值。
比如private byte maxPlayersPerRoom = 4;
這個值確實可以應(yīng)用到每個房間的設(shè)置上。用以限定房間最大玩家數(shù)。
另外可以在此變量上方添加一個注釋:[Tooltip(“注釋”)]。

現(xiàn)在就可以通過實例化RoomOptions對象時設(shè)定最大玩家數(shù),需要了解的是,此時不再是構(gòu)造函數(shù)進行實例化。反而是大括號內(nèi)書寫這個類中的公共變量的定義。

//現(xiàn)在不僅創(chuàng)建了房間,還通過設(shè)定建立了一個具有最大玩家數(shù)的房間。 PhotonNetwork.CreateRoom(null, new RoomOptions { MaxPlayers = maxPlayersPerRoom });

現(xiàn)在在代碼中使用了maxPlayerPerRoom的值去創(chuàng)建一個房間。如果人滿了,那么這個房間將不再接收其他人的加入。


現(xiàn)在可以做一個UI,當(dāng)點擊按鈕時(比如登錄)再連接這個服務(wù)器。
這么做算是unity基礎(chǔ)了,不多說。

玩家昵稱

下面進行玩家昵稱的相關(guān)代碼編寫。
官方文檔是針對隨意設(shè)置昵稱,不講求賬號的區(qū)別性的教程。與項目內(nèi)容有點出入。
下面按照所學(xué),結(jié)合項目需求進行改寫:(昵稱即賬號)
首先說明一下執(zhí)行邏輯:
玩家點擊登錄 → 向自開發(fā)服務(wù)端發(fā)送pack → 若驗證成功 → 玩家客戶端將登錄賬號作為昵稱然后連接pun服務(wù)端。

此時就需要一個變量保存玩家賬號。
當(dāng)解析完服務(wù)端發(fā)來的pack確定登錄成功后,

  • 把賬號保存到PlayerPrefs哈希表里(記住賬號方便以后輸入)。
  • 設(shè)置PhotonNetwork.NickName,再調(diào)用Connect()連接。
  • 若連接成功則跳轉(zhuǎn)場景(確保登錄場景中的GameFace物體保留、那上面掛載著socket腳本)。
  • 連接失敗則UI提示。
  • 游客線上模式仍然需要存儲在PlayerPrefs里的,盡量方便每次重新打開游戲時的使用,不用再需要用戶手動輸入。
    游客模式下的GUI可以參考PUN Basics Tutorial–2–Creating The UI For The Player’s Name。
    在InputField上掛在一個腳本并且實現(xiàn)OnValueChanged回調(diào)函數(shù)實時設(shè)置PhotonNetwork.NickName和保存到PlayerPrefs。

    在開始連接之后,從人機交互角度上來說,有一個動畫效果顯示當(dāng)前正在連接會帶來更好的體驗,同樣這也是官方所建議的。
    這通過SetActive()就可以隨意控制,當(dāng)然稍微復(fù)雜點也可以實現(xiàn)自己的UI代碼框架進行彈出窗體。

    到此為止是PUN框架的昵稱、連接主服務(wù)器和大廳、房間等API的學(xué)習(xí)。
    具體項目代碼和GUI設(shè)計見下一篇。


    總結(jié)

    以上是生活随笔為你收集整理的项目实训--Unity多人游戏开发(九、PUN2学习记录)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。