准备设置
打开项目后,进入Window/Services视图。
创建或登录项目ID进入下面面板。
选择Multiplayer进入
选择GoToDashboard进入网页(登录Unity账号)
选择下方OK,进入
括号中填入每个房间最多玩家数量后,选择Save。
进入此界面即可。
项目制作
这里使用Unity Unet(三)Unet局域网游戏框架中项目。
将项目中Network的Maximum Match Size改为上面设置的数量。
创建按钮
代码调整:
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.Networking.Match;
using UnityEngine.SceneManagement;
public class NetworkManagerCustom : NetworkManager
{
public static void LanGame()
{
singleton.StartCoroutine((singleton as NetworkManagerCustom).DiscoveryNetwork());//singleton单例
}
public IEnumerator DiscoveryNetwork()
{
NetworkDiscoveryCustom discovery = GetComponent<NetworkDiscoveryCustom>();//获取组件
discovery.Initialize();//组件初始化
discovery.StartAsClient();//作为客户端运行,扫描局域网的服务器,如果有就加入(自动调用NetworkDiscoveryCustom中的OnReceivedBroadcast)。
yield return new WaitForSeconds(2);//等待2秒
if (discovery.running)//2秒后仍未找到服务器…
{
discovery.StopBroadcast();//停止广播包
yield return new WaitForSeconds(0.5f);//等待0.5秒
discovery.StartAsServer();//作为服务器,发射广播包。
StartHost();//作为服务器和客户端同时启动
}
}
public static void NetGame()
{
singleton.StartMatchMaker();//启用Unet网络对战功能
//参考文档:https://docs.unity3d.com/ScriptReference/Networking.Match.NetworkMatch.ListMatches.html
//无力解释,下面为百度翻译直译
//参数一:startPageNumber:要在返回结果中列出的当前页。
//参数二:resultPageSize:请求的页面大小。这决定了在回调中传递的匹配列表中包含的最大匹配数。
//参数三:matchNameFilter:文本字符串名称筛选器。这是针对当前活动的匹配名称的部分通配符搜索,可以认为是与*<matchNameFilter>*匹配等价,其中包含此处提供的整个字符串的任何结果都将位于结果集中。
//参数四:filterOutPrivateMatchesFromResults:指示响应是否应包含私有匹配项(即受密码保护的匹配项)的布尔值。
//参数五:eloScoreTarget:要分组的匹配列表结果的Elo分数目标。如果使用,则应将其设置为列出匹配项的客户端的Elo级别,以便结果更接近该玩家的技能级别。如果不使用,则可以将其与NetworkMatch.CreateMatch或NetworkMatch.JoinMatch等函数中的所有其他Elo引用一起设置为0。
//参数六:requestDomain:此请求的请求域。只有同一域中的请求才能相互连接。例如,如果使用域1生成NetworkMatch.CreateMatch,则只有同时指定域1的ListMatches才会找到该匹配项。使用此值可以隔离不同(可能不兼容)的客户端版本。
//参数七:callback:此次请求完成后的回调。
singleton.matchMaker.ListMatches(0,20,"",false,0,0,singleton.OnMatchList);
}
//回调
public override void OnMatchList(bool success, string extendedInfo, List<MatchInfoSnapshot> matchList)
{
if (!success) return;
if (matchList != null)
{
//保存玩家没有满的房间情况
List<MatchInfoSnapshot> availableMatches = new List<MatchInfoSnapshot>();
foreach (MatchInfoSnapshot match in matchList)
{
if (match.currentSize< match.maxSize)
{
availableMatches.Add(match);
}
}
//列表数量:为0则创建服务器,不为0则加入服务器
if (availableMatches.Count == 0)
{
//创建服务器
CreateMatch();
}
else
{
//加入服务器
matchMaker.JoinMatch(availableMatches[UnityEngine.Random.Range(0,availableMatches.Count-1)].networkId,"","","",0,0,OnMatchJoined);
}
}
}
//Unet创建网络服务器
void CreateMatch()
{
//参数一:matchName:房间名称
//参数二:matchSize:房间最大玩家数量。如填入matchSize,自动获取物体Network的Maximum Match Size的值
//参数三:matchAdvertise:
//参数四:matchPassword:口令/密码
//参数五:publicClientAddress:链接地址(公网)
//参数六:privateClientAddress:私网地址
//参数七:eloScoreForMatch
//参数八:requestDomain:域,填入值与上面singleton.matchMaker.ListMatches参数六:requestDomain相同
//参数九:callback
matchMaker.CreateMatch("",matchSize,true,"","","",0,0,OnMatchCreate);
}
public override void OnMatchCreate(bool success, string extendedInfo, MatchInfo matchInfo)
{
if (!success) return;
StartHost(matchInfo);//利用Unet返回的matchinfo创建服务器
}
public override void OnMatchJoined(bool success, string extendedInfo, MatchInfo matchInfo)
{
if (!success)
{
int currentScene = SceneManager.GetActiveScene().buildIndex;
SceneManager.LoadScene(currentScene);
return;
}
StartClient(matchInfo);//利用Unet传回的matchinfo启动客户端
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class IndexUI : MonoBehaviour
{
public void NetButtonClick()
{
NetworkManagerCustom.NetGame();
}
public void LanButtonClick()
{
NetworkManagerCustom.LanGame();
}
}
将NetButtonClick函数绑定在按钮上。