完成后简单的样子就是这样了,不行的可以自己修改一下,大概写的各种逻辑给大家一个参考标准,毕竟现在大厅的资料略少啊,官方AIP也是一坨屎,各种不清楚;
1:创建lobbymanager,这个和networkmanager大同小异
using UnityEngine; using System.Collections; using UnityEngine.Networking; using UnityEngine.SceneManagement; using UnityEngine.Networking.Match; using System.Collections.Generic; public class MyLobbyManager : NetworkLobbyManager { //单利管理器 public static MyLobbyManager instance; //是否开启场景切换 public bool beginChange = false; //玩家编号 private int playerPositionIndex = 0; //背景音乐 public GameObject backAud; //当前连接数量 public int Playernumber = 0; void Awake() { instance = this; StartMatchMaker (); RequestPage (); } public void RequestPage() { matchMaker.ListMatches(0, 10, "", true, 0, 0, GameController.instance.OnMatchList); } // Use this for initialization void Start () { DontDestroyOnLoad (backAud); } /// <summary> /// 当所有玩家都已准备完毕 /// </summary> public override void OnLobbyServerPlayersReady () { //启动协程等待动画播放完毕 StartCoroutine (PlayProgress ()); //遍历所有客户端发送播放指令 foreach (NetworkLobbyPlayer item in lobbySlots) { if (item) { (item as MyLobbyPlayer).RpcBeginPlay (); } } } IEnumerator PlayProgress() { while (!beginChange) yield return null; base.OnLobbyServerPlayersReady (); } //当服务器添加玩家对象调用 public override void OnServerAddPlayer(NetworkConnection conn, short playerControllerId) { base.OnServerAddPlayer (conn, playerControllerId); Playernumber++; //判断是在大厅还是在游戏 if (beginChange) { //创建角色 GameObject player = Instantiate(gamePlayerPrefab) as GameObject; //通过新场景的NetworkStartPosition确定泰克的创建位置 player.transform.position = startPositions[Playernumber++].position; //设置角色的网络变量编号 player.GetComponent<GamePlayer>().playerNum = playerPositionIndex - 1; //给予使用权限 NetworkServer.AddPlayerForConnection(conn,player,playerControllerId); //出生了孩子 NetworkServer.Spawn(player); } } public override void OnMatchCreate(bool success,string extendedInfo,MatchInfo matchInfo) { base.OnMatchCreate (success,extendedInfo,matchInfo); } }
2:UI,大厅一般都是在UI上面完成的
首相创建一个画布,创建一个image
把一下脚本加入到lobbyUI管理里面
using UnityEngine; using UnityEngine.UI; using UnityEngine.Networking; using UnityEngine.Networking.Match; using System.Collections.Generic; public class GameController : MonoBehaviour { //单利脚本 public static GameController instance; //UI public Button host; public Button back; public Button join; public InputField ip; public InputField matchNameInput; public GameObject content; public GameObject playerChoosePanel; public GameObject playerListPanel; public GameObject SevercontentPanel; public RectTransform Severcontent; public GameObject severEntryPrefab; //lobbyManager private MyLobbyManager manager; void Awake() { instance = this; } // Use this for initialization void Start () { manager = MyLobbyManager.instance; } void OnEnable () { //取消创建主机和加入服务器的按钮事件监听 host.onClick.RemoveAllListeners (); join.onClick.RemoveAllListeners (); //设置创建主机和加入服务器的按钮事件监听 host.onClick.AddListener (OnHostButtonClick); join.onClick.AddListener (OnJoinButtonClick); } //创建本地主机 public void OnHostButtonClick() { //启动主机 manager.StartHost(); manager.Playernumber++; //切换UI PanelSwitch (true); //设置返回按键的监听事件 back.onClick.RemoveAllListeners(); back.onClick.AddListener (StopHost); } //创建主机 public void OnClickCreateMatchmackingGame() { manager.StartMatchMaker (); manager.matchMaker.CreateMatch ( matchNameInput.text, (uint)manager.maxPlayers, true, "","","",0,0, manager.OnMatchCreate); SetUI (); } public void SetUI() { //切换UI PanelSwitch (true); //设置返回按键的监听事件 back.onClick.RemoveAllListeners(); back.onClick.AddListener (StopHost); } //加入房间按钮事件监听 public void OnJoinButtonClick() { //如果输入有IP if (ip.text != "") { //设置IP manager.networkAddress = ip.text; } //启动客户端 manager.StartClient(); //切换UI PanelSwitch (true); //设置此时返回按键事件监听 back.onClick.RemoveAllListeners(); back.onClick.AddListener (StopClient); } public void OnMatchList(bool success, string extendedInfo, List<MatchInfoSnapshot> matches) { //清空列表 foreach (Transform t in Severcontent) Destroy (t.gameObject); //创建新的房间列表 for (int i = 0; i < matches.Count; ++i) { GameObject obj = Instantiate (severEntryPrefab) as GameObject; obj.GetComponent<LobbyServerEntry> ().Populate (matches[i]); obj.transform.SetParent (Severcontent,false); } } public void OnRefrashMachList() { manager.RequestPage (); } //停止服务器 public void StopHost() { manager.StopHost (); PanelSwitch (false); } //停止客户端 public void StopClient() { manager.StopClient (); PanelSwitch (false); } //切换UiPanel public void PanelSwitch(bool toListPanel) { if (toListPanel) { playerListPanel.SetActive (true); playerChoosePanel.SetActive (false); SevercontentPanel.SetActive (false); } else { playerListPanel.SetActive (false); playerChoosePanel.SetActive (true); SevercontentPanel.SetActive (true); } } //设置父子关系 public void SetParent(Transform child) { child.SetParent (content.transform); } }
3:创建一个房间用itemplayer
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using UnityEngine.Networking; public class MyLobbyPlayer : NetworkLobbyPlayer { //玩家大厅显示名称 private Transform content; //玩家大厅准备按钮 private Button readyButton; //单利lobbyManager private MyLobbyManager manager; // Use this for initialization void Awake() { manager = MyLobbyManager.instance; content = GameController.instance.content.transform; readyButton = transform.GetChild (0).GetComponent<Button> (); } void Start () { //设置当前对象到显示的UI中 GameController.instance.SetParent (this.transform); transform.localScale = Vector3.one; //非主机客户端更新玩家名称 if (!isServer) { CmdUpdateItemName (); } } [Command] public void CmdUpdateItemName () { //服务器开始下发指令 RpcUpdateItemName(); } [ClientRpc] public void RpcUpdateItemName () { int i = 0; for (; manager.lobbySlots [i]; ++i) ; Debug.Log ("" + i); //非主机客户端设置字体颜色 content.GetChild (1).GetComponent<Image> ().color = Color.red; //非主机客户端设置玩家名称 content.GetChild (1).GetChild (1).GetComponent<Text> ().text = "Player" + manager.Playernumber; } //本地执行 public override void OnStartLocalPlayer () { base.OnStartLocalPlayer (); //设置准备按钮可用 readyButton.interactable = true; //移除所有监听 readyButton.onClick.RemoveAllListeners (); //设置准备按钮事件监听 readyButton.onClick.AddListener (OnReadyButtonClick); } //玩家准备按钮点击事件 public void OnReadyButtonClick() { //向服务器发送准备指令 SendReadyToBeginMessage(); //移除按键监听 readyButton.onClick.RemoveAllListeners(); //设置按钮取消事件 readyButton.onClick.AddListener(OnNotReadyButtonClick); } //玩家取消准备按钮点击事件 public void OnNotReadyButtonClick() { //向服务求发送取消指令 SendNotReadyToBeginMessage(); //取消按钮所有指令 readyButton.onClick.RemoveAllListeners(); //添加指令 readyButton.onClick.AddListener(OnReadyButtonClick); } public override void OnClientReady(bool readyState) { base.OnClientReady (readyState); //如果准备好了 if (readyState) { readyButton.GetComponentInChildren<Text> ().text = "Done"; } else { readyButton.GetComponentInChildren<Text>().text = "Ready"; } } [ClientRpc] //客户端开始放切换场景动画 public void RpcBeginPlay() { } }
4:最后就是大厅房间显示出来让人可以加入了
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using UnityEngine.Networking; using UnityEngine.Networking.Match; using UnityEngine.Networking.Types; public class LobbyServerEntry : MonoBehaviour { public Text serverInfoText; public Text slotInfo; public Button joinButton; private MyLobbyManager manager; void Awake() { manager = MyLobbyManager.instance; } public void Populate(MatchInfoSnapshot match) { serverInfoText.text = match.name; slotInfo.text = match.currentSize.ToString () + "/" + match.maxSize.ToString (); NetworkID networkID = match.networkId; joinButton.onClick.RemoveAllListeners (); joinButton.onClick.AddListener (() => {JoinMatch(networkID);}); } void JoinMatch(NetworkID networkID) { manager.matchMaker.JoinMatch (networkID,"","","",0,0,manager.OnMatchJoined); GameController.instance.SetUI (); } }