完成后简单的样子就是这样了,不行的可以自己修改一下,大概写的各种逻辑给大家一个参考标准,毕竟现在大厅的资料略少啊,官方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 ();
}
}