项目实训--Unity多人游戏开发(十、游戏GUI界面与PUN大厅房间)
文章目錄
- 界面設計
- GUI與PUN代碼結構(調用關系)
- 項目代碼
- 官方demo學習結果
- 官方文檔學習筆記--退出房間(與實際需求有偏差,可不看)
- 待更新點及總結
界面設計
初始界面
背景暫時放一張糖豆人的海報,界面這部分是和小組其他成員一起制作的。其他成員的博客可以在小組的綜述里找到。
登錄注冊
請忽略后面的黃色字體和充滿違和感的素材。還沒有到GUI美化階段。
大廳界面
創建房間界面
見下下下面↓
GUI與PUN代碼結構(調用關系)
AppManager.cs負責各種監聽函數、GUI顯示邏輯等。
Launcher.cs繼承PunCallbacks,實現Pun相關的內容。
這兩部分代碼搭配使用。
GUI操作→調用pun;
pun結果→GUI反饋。
項目代碼
下面進行大廳功能的開發。
當加入主服務器后,我們需要的功能是加入大廳并且顯示房間列表而不是直接隨機加入到某個房間中。
而且如果要進行創建房間,必須要先在大廳/主服務器中才可以。
修改OnConnectedToMaster回調:
lobbyPanel:(粗略的制作了一下,GUI美化在后期)
中間的列表區域是一個Unity的UI對象ScrollView。(已刪除水平滾動條)
房間會被加入到Content中顯示,別忘了給Content加一個GridLayoutGroup組件。并且調整內部元素的大小。
房間列表的顯示可以通過pun官方的回調函數OnRoomListUpdate來寫。
點擊創建房間后會彈出創建面板。
確定按鈕的監聽。
現在已經可以建立房間和顯示房間了,但是還沒有制作加入房間等功能。
另外提示一下,unity中導入Pun2插件后,可以找到官方的demo,里面具有游戲同步和房間大廳的代碼,如下圖
當然再Scenes里可以找到場景并且進行多人游玩。(前提是配置好pun的AppID等)
官方demo學習結果
通過上述官方demo的學習。
先講一下大致框架:
創建房間后仍然調用Photon的官方API。
這里因為房間需要復用。把房間作為一個預制體。
這里只顯示最基本的房間信息以及一個按鈕。
有其他需要可以擴展。不過要結合pun框架哦。
在之前的OnRoomListUpdate回調里,需要改一下了:
public override void OnRoomListUpdate(List<RoomInfo> roomList){//...這些代碼沒變//變動↓foreach (var room in roomList)//顯示在list中的每個房間{GameObject entry = Instantiate(roomEntryPrefab, gridLayoutGroup_content.position, Quaternion.identity);entry.transform.SetParent(gridLayoutGroup_content);//entry.transform.localScale = Vector3.one;//調用entry(預制體)上掛的腳本的初始化方法,把房間名等信息傳到UI。entry.GetComponent<RoomEntry>().Initialize(room.Name, (byte)room.PlayerCount, room.MaxPlayers);}}然后這樣列表里會逐一顯示“房間名稱”、“在線人數/最大人數”、“加入按鈕”的房間。
具體RoomPrefab內部布局這里不提及。UI按照個人意愿做就好了。可以使用UI的一些布局組件“Horizontal Layout Group”。
然后看一下掛在RoomPrefab上的腳本:
RoomEntry.cs:
現在可以生成房間并且顯示房間了。
那么創建房間或點擊加入房間之后該顯示什么呢?
下一步制作RoomPanel。
這個panel不需要做成預制體,根本不需要復用,用SetActive(bool)控制它的顯示與否就可以了。
預制體包含:
另外最重要的就是顯示玩家了,而且還要有準備功能!
為此創建一個PlayerEntryPrefab。
共四個子UI:
一個用于區分玩家的顏色顯示塊。
玩家昵稱。
準備與取消準備按鈕。
準備狀態圖片。
但是代碼就復雜起來了。也需要用到更高深的API。
如何知道玩家有沒有準備?如何同步準備信息?如何給定當前房間的玩家一個永久對應的顏色?
官方demo是這么做的(有少許改動):
PlayerEntry腳本,掛在預制體上:
傳遞每個客戶端的消息(準備情況),用的是SetCustomProperties,這都是pun封裝好的方法,用來修改這個玩家對應的一些屬性,有監聽修改的回調函數。玩家屬性有改動則會執行這個回調。可以檢測有沒有都準備。
OnPlayerPropertiesUpdate():
由以上代碼,當全部玩家準備后,房主那邊才可以點擊開始游戲。
開始游戲按鈕的監聽里可以調用PhotonNetwork.LoadLevel("SceneName");,啟動游戲場景。按照前幾篇博文,只要開啟了同步加載場景,那么其他玩家會同步加載游戲。
官方文檔學習筆記–退出房間(與實際需求有偏差,可不看)
首先要明確不同人數的游戲房間,地形大小也是不同的,軟件應該為用戶帶來良好體驗,而游戲中有足夠大的空間會增強這一點。
還要實現一個退出房間的功能,先做一個GameManager預制體并附上一個腳本(不同場景中會復用GameManager),腳本包含點擊事件對應的函數LeaveRoom及退出房間的回調函數OnLeftRoom。
同時做一個按鈕預制體。為其監聽器添加LeaveRoom。
按鈕制作這里可以修改RectTransform的錨點,按shift和alt鍵設置為top和stretch。RectTransform是UI特有組件。這里涉及到錨點/錨框的知識點,說白了就是相對布局與絕對布局的概念。
然后我們需要玩家加入或退出房間后加載場景,這用到兩個回調函數OnPlayerEnteredRoom和OnPlayerLeftRoom。代碼如下
public override void OnPlayerEnteredRoom(Player other) {Debug.LogFormat("OnPlayerEnteredRoom() {0}", other.NickName); // not seen if you're the player connectingif (PhotonNetwork.IsMasterClient){Debug.LogFormat("OnPlayerEnteredRoom IsMasterClient {0}", PhotonNetwork.IsMasterClient); // called before OnPlayerLeftRoomLoadArena();} }public override void OnPlayerLeftRoom(Player other) {Debug.LogFormat("OnPlayerLeftRoom() {0}", other.NickName); // seen when other disconnectsif (PhotonNetwork.IsMasterClient){Debug.LogFormat("OnPlayerLeftRoom IsMasterClient {0}", PhotonNetwork.IsMasterClient); // called before OnPlayerLeftRoomLoadArena();} }#region Private Methods void LoadArena() {if (!PhotonNetwork.IsMasterClient){Debug.LogError("PhotonNetwork : Trying to Load a level but we are not the master Client");}Debug.LogFormat("PhotonNetwork : Loading Level : {0}", PhotonNetwork.CurrentRoom.PlayerCount);PhotonNetwork.LoadLevel("Room for " + PhotonNetwork.CurrentRoom.PlayerCount); } #endregion要注意PhotonNetwork.LoadLevel是只有房主才能調用的方法。當所有客戶端開啟了同步加載場景后會自動跟隨加載場景。
官方文檔到此之后的代碼與要完成的功能有點區別。
有一點要注意的是必要時可以用一個bool變量存儲用戶的連接狀態并作為后續代碼執行條件。避免用戶在退出房間時執行了并不需要的功能。
待更新點及總結
至于玩家顏色方面
通過Photon.Realtime.Player.GetPlayerNumber()玩家編號來獲得不同顏色。
但是好像涉及到玩家編號改變的情況(玩家進入退出房間),demo用了委托,還額外有一個"PlayerNumbering.cs"腳本,暫時還沒看懂有什么用。
后續有時間再看一下吧。
下一步就可以學習游戲的同步了。這里才是重頭戲。將會新開一篇博文。
總結
以上是生活随笔為你收集整理的项目实训--Unity多人游戏开发(十、游戏GUI界面与PUN大厅房间)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ssm框架bean_Bean简介:简化的
- 下一篇: 实例理解月末结账任务中,重估未结外币余额