UNet组件是unity自带制作网络游戏的强大组件,在unity5.x之前叫做NetworkView,之后新为UNet。刚开始接触UNet,开始第一步旅行。首先大致了解一下UNet制作局域网游戏的框架。
首先上图,了解下NetworkManger和Network Discovery两个组件;
这是unity提供的2个组件,也是我们要用的组件,其参数后面进行详解~
(1)制作两个场景,Scene1为开始场景(UI场景),Scene2为游戏主场景(Game场景),这个就不说了(太过Easy~);
(2)编写UNet框架,直接上代码吧,有注释哟~
~~~~~NetworkDiscoveryCustom.cs~~~~~~
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
/// <summary>
/// 扫描局域网
/// </summary>
public class NetworkDiscoveryCustom : NetworkDiscovery {
//
public override void OnReceivedBroadcast(string fromAddress, string data)
{
StopBroadcast();
NetWorkMangerCustom.singleton.networkAddress = fromAddress;
NetWorkMangerCustom.singleton.StartClient();
}
}
~~~~~~NetworkMangerCustom.cs~~~~~
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.Networking.Match;
using UnityEngine.SceneManagement;
public class NetWorkMangerCustom : NetworkManager {
// 单人模式
public static void SingPerson()
{
singleton.StartHost(singleton.connectionConfig, 1);
}
// 局域网模式
public static void LanGame()
{
singleton.StartCoroutine((singleton as NetWorkMangerCustom).DiscoveryNetwork());
}
/// <summary>
/// 开启协程扫描局域网
/// </summary>
/// <returns></returns>
public IEnumerator DiscoveryNetwork()
{
NetworkDiscovery discovery = GetComponent<NetworkDiscoveryCustom>();
discovery.Initialize(); // 初始化
discovery.StartAsClient(); // 扫描局域网内的服务器,如果有,就直接加入
yield return new WaitForSeconds(1);
// 如果没有找到局域网内的服务器
if (discovery.running)
{
discovery.StopBroadcast(); // 停止广播
yield return new WaitForSeconds(0.5f);
discovery.StartAsServer(); // 把自己作为服务器,进行广播
StartHost(); // 同时作为服务端 and 客户端启动
//StartServer(); // 只作为服务端
//StartClient(); // 只作为客户端
}
}
// 网络模式
public static void NetGmae()
{
singleton.StartMatchMaker(); // 表示UNet网络功能,发起请求
singleton.matchMaker.ListMatches(0,4,"",false,0,0,singleton.OnMatchList);
// 参数1:表示list的第几页
// 参数2:表示每一页的个数
// 参数3:目标房间的名称
// 参数4:是否返回带有密钥的房间
// 参数5:关于竞赛方面的设置?(不明白)
// 参数6:一个 "域" ,表示只能从这个 "域" 上返回房间
// 参数7:回调函数
}
public override void OnMatchList(bool success, string extendedInfo, List<UnityEngine.Networking.Match.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
if (availableMatches.Count == 0)
{
// 创建服务器
CreateMatch();
}
else
{
// 加入服务器
matchMaker.JoinMatch(availableMatches[Random.Range(0,availableMatches.Count - 1)].networkId,"","","",0,0,OnMatchJoined);
}
}
}
/// <summary>
/// 通知UNet创建网络服务器
/// </summary>
void CreateMatch()
{
matchMaker.CreateMatch("",matchSize,true,"","","",0,0,OnMatchCreate);
// 参数1:房间名
// 参数2:房间中的玩家数
// 参数3:
// 参数4:服务器密码
// 参数5:Client IP地址(公网)
// 参数6:私网地址
// 参数7:
}
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);
}
}
~~~~添加Button事件~~~~~~
以上就是本次全部代码啦~~
(3)在主场景中添加游戏物体,然后将其制作为预制体,并添加NetworkIdentity标识!
(4)在主场景中创建一个空物体,将上面的NetworkManger和Network Discovery添加到空物体上
(5)注意:一定要将主场景添加到途中OnlineScene中,打开SpawnInfo,将Player Prefab选中为当前游戏物体预制体
(6)将Scene1和Scene2添加到BuildSettings里面,点击Build
(7)运行Build后生成的 exe 程序,就会有如下效果:
这是两个客户端运行结果,可以看到两个客户端均创建了2游戏物体Cube