本文主要来实现一下自定UI(实现HUD的功能),并对Network Manger进行深入的讲解。

1)自定义manager

创建脚本CustomerUnetManger,并继承自NetworkManger,并对相关虚函数进行重载,并简单写了几个外部调用方法。完整脚本在文末,部分截图如下:

其中LogInfo为debug用,完整脚本在文末

2)UI脚本CustomerUnetMainMenu

编写脚本,实现自定义新建Server client 以及host,再次着重说一下原NetworkMangerHUD脚本中的第四个方法,即NetworkManger中的matchmaker。matchmaker通过unity提供的网络服务,建立游戏,然后通过你自己生成的exe就可以获取到建立的游戏列表,然后可以加入游戏:

首先开启matchmaker

    /// <summary>
/// UI调用,MatchMaker
/// </summary>
public void StartMatchMaker_()
{
if (!IsClientConnected() && !NetworkServer.active && matchMaker == null)
{
StartMatchMaker();
matchMode = true;
}
}

然后建立游戏

    /// <summary>
/// UI调用,创建比赛
/// </summary>
public void CreateMatch_()
{
if (matchMaker != null)
{
matchMaker.CreateMatch("LLMatch", , true, "", "", "", , , OnMatchCreate);
}
}

获取游戏列表(获取列表并UI显示时需要脚本match Button)

matchMaker.ListMatches(, , "", true, , , OnMatchList);

加入游戏

    /// <summary>
/// 加入指定的比赛
/// 对于建立比赛的player,本身已经在游戏中,所以不能再次加入(已经生成host)
/// 对于建立比赛的player,在加入其他游戏时先取消比赛(DestroyMatch)
/// 对于加入比赛的player,只能加入一次,不能重复加入(已经生成client)
/// 对于加入比赛的Player,在重复加入或者加入其他游戏之前先断开连接(DropConnection)
/// 本程序为demo,上述问题不做处理
/// </summary>
/// <param name="jointMatch"></param>
public void JoinMatch(MatchInfoSnapshot jointMatch)
{
if (matchMaker == null) StartMatchMaker(); matchMaker.JoinMatch(jointMatch.networkId, "", "", "", , , OnMatchJoined);//调用此方法时生成client
}

3)此部分到此基本结束没有太大问题,一些注意事项已经在代码中注释,至于如何退出比赛等会再下一篇LobbyManager中进行解释,下边时此工程的所有脚本文件。再次说明一下,玩家预制体等均采用上一篇。此工程为demo,所以UI简陋,可能会有不友好的操作或者逻辑bug

//——————————————————————————————脚本————————————————————————————//

using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.Networking.Match; public class CustomerUnetManger : NetworkManager
{
public Action<List<MatchInfoSnapshot>> ListMatchAction; private float refreshTime = ;
private bool matchMode = false; #region SERVER CALLBACKS
public override void OnServerReady(NetworkConnection conn)
{
LogInfo.theLogger.Log("Server ready"); base.OnServerReady(conn);
} public override void OnStartServer()
{
LogInfo.theLogger.Log("Server start"); base.OnStartServer();
} public override void OnServerConnect(NetworkConnection conn)
{
LogInfo.theLogger.Log("Server connect"); base.OnServerConnect(conn);
} public override void OnServerDisconnect(NetworkConnection conn)
{
LogInfo.theLogger.Log("Server disconnect"); base.OnServerDisconnect(conn);
} public override void OnServerAddPlayer(NetworkConnection conn, short playerControllerId)
{
LogInfo.theLogger.Log("Server add player"); base.OnServerAddPlayer(conn, playerControllerId);
} public override void OnServerRemovePlayer(NetworkConnection conn, PlayerController player)
{
LogInfo.theLogger.Log("Server remove player"); base.OnServerRemovePlayer(conn, player);
} public override void OnServerError(NetworkConnection conn, int errorCode)
{
LogInfo.theLogger.Log("Server error"); base.OnServerError(conn, errorCode);
} public override void OnStartHost()
{
LogInfo.theLogger.Log("Host start"); base.OnStartHost();
} public override void OnStopHost()
{
LogInfo.theLogger.Log("Host stop"); base.OnStopHost();
} public override void OnStopServer()
{
LogInfo.theLogger.Log("Server stop"); base.OnStopServer();
}
#endregion #region CLIENT CALLBACKS
public override void OnClientConnect(NetworkConnection conn)
{
LogInfo.theLogger.Log("Client connect"); base.OnClientConnect(conn);
} public override void OnClientDisconnect(NetworkConnection conn)
{
LogInfo.theLogger.Log("Client disconnect"); base.OnClientDisconnect(conn);
} public override void OnClientError(NetworkConnection conn, int errorCode)
{
LogInfo.theLogger.Log("Client error"); base.OnClientError(conn, errorCode);
} public override void OnStartClient(NetworkClient client)
{
LogInfo.theLogger.Log("Client start"); base.OnStartClient(client);
} public override void OnStopClient()
{
LogInfo.theLogger.Log("Client stop"); base.OnStopClient();
}
#endregion #region MATCHMAKER CALLBACKS
public override void OnMatchCreate(bool success, string extendedInfo, MatchInfo matchInfo)
{
LogInfo.theLogger.Log("Match create"); //MatchCreate结束后进行OnMatchCreate回调,而在base中OnMatchCreate时会
//立马创建host(即创建一个server和client),所以当重复创建match时报错
//为避免此类问题可以在OnMatchCreate中不调用base的OnMatchCreate,通过自行创建List<MatchInfoSnapshot>变量自己存储比赛(matches)
//然后在需要创建host时,再startHost,但是一般游戏时只允许玩家创建一个游戏,创建另一个游戏时需退出当前游戏
base.OnMatchCreate(success, extendedInfo, matchInfo);
matchMaker.ListMatches(, , "", true, , , OnMatchList);
} public override void OnMatchJoined(bool success, string extendedInfo, MatchInfo matchInfo)
{
LogInfo.theLogger.Log("Match joint"); base.OnMatchJoined(success, extendedInfo, matchInfo);
} public override void OnMatchList(bool success, string extendedInfo, List<MatchInfoSnapshot> matchList)
{
LogInfo.theLogger.Log("Match list:"+ matchList.Count);//基函数的OnMatchList把matchList赋值给matches,此处matches仍为初始值 base.OnMatchList(success, extendedInfo, matchList); if(ListMatchAction!=null)
{
ListMatchAction(matchList);
}
//LogInfo.theLogger.Log("Match list:" + matches.Count);
}
#endregion #region CONTROLL METHODS
/// <summary>
/// UI调用,开启server
/// </summary>
public void StartServer_()
{
if (!IsClientConnected() && !NetworkServer.active && matchMaker == null)
{
StartServer();
}
} /// <summary>
/// UI调用,开启Host
/// </summary>
public void StartHost_()
{
if (!IsClientConnected() && !NetworkServer.active && matchMaker == null)
{
StartHost();
}
} /// <summary>
/// UI调用,开启client
/// </summary>
public void StartClient_()
{
if (!IsClientConnected() && !NetworkServer.active && matchMaker == null)
{
StartClient();
}
} /// <summary>
/// UI调用,MatchMaker
/// </summary>
public void StartMatchMaker_()
{
if (!IsClientConnected() && !NetworkServer.active && matchMaker == null)
{
StartMatchMaker();
matchMode = true;
}
} /// <summary>
/// UI调用,停止服务
/// </summary>
public void StopAllService()
{
if (NetworkServer.active || IsClientConnected())
{
StopHost();
} if (client != null && NetworkClient.active)
{
StopClient();
} if (matchMaker != null)
{
StopMatchMaker();
matchMode = false;
}
} /// <summary>
/// UI调用,创建比赛
/// </summary>
public void CreateMatch_()
{
if (matchMaker != null)
{
matchMaker.CreateMatch("LLMatch", , true, "", "", "", , , OnMatchCreate);
}
}
/// <summary>
/// 加入指定的比赛
/// 对于建立比赛的player,本身已经在游戏中,所以不能再次加入(已经生成host)
/// 对于建立比赛的player,在加入其他游戏时先取消比赛(DestroyMatch)
/// 对于加入比赛的player,只能加入一次,不能重复加入(已经生成client)
/// 对于加入比赛的Player,在重复加入或者加入其他游戏之前先断开连接(DropConnection)
/// 本程序为demo,上述问题不做处理
/// </summary>
/// <param name="jointMatch"></param>
public void JoinMatch(MatchInfoSnapshot jointMatch)
{
if (matchMaker == null) StartMatchMaker(); matchMaker.JoinMatch(jointMatch.networkId, "", "", "", , , OnMatchJoined);//调用此方法时生成client
}
#endregion private void Update()
{
//取消了实时更新列表,可以测试使用
//if(Time.time>refreshTime && matchMode)
//{
// if (matchMaker == null) StartMatchMaker(); // matchMaker.ListMatches(0, 5, "", true, 0, 0, OnMatchList); // refreshTime += 4;
//}
}
}
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.Networking.Match;
using UnityEngine.UI; public class CustomerUnetMainMenu : MonoBehaviour
{
public Button serverButton;
public Button hostButton;
public Button clinetButton;
public Button matchMakerButton;
public Button stopButton;
public Button createMatchButton; public GameObject starts;
public GameObject matches;
public CustomerUnetManger theManager;
public MatchListRefresher refresher; private bool matchCreated = false; #region BUTTON METHODS private void StartServer()
{
theManager.StartServer_();
} private void StartHost()
{
theManager.StartHost_();
} private void StartClient()
{
theManager.StartClient_();
} private void StartMatchMaker()
{
theManager.StartMatchMaker_(); matches.SetActive(true);
starts.SetActive(false);
} private void Stop()
{
theManager.StopAllService(); matches.SetActive(false);
starts.SetActive(true);
matchCreated = false;
} private void CreateMatch()
{
if(!matchCreated)
{
theManager.CreateMatch_();
matchCreated = true;
}
} #endregion private void Start()
{
serverButton.onClick.AddListener(StartServer);
hostButton.onClick.AddListener(StartHost);
clinetButton.onClick.AddListener(StartClient);
matchMakerButton.onClick.AddListener(StartMatchMaker);
stopButton.onClick.AddListener(Stop);
createMatchButton.onClick.AddListener(CreateMatch); theManager.ListMatchAction += OnListMatch;
} private void OnListMatch(List<MatchInfoSnapshot> list)
{
refresher.RefreshList(list);
}
}
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking.Match; public class MatchListRefresher : MonoBehaviour
{
[SerializeField]
private GameObject matchButton; //直接清除列表的刷新的方式不好,可通过一下两种方法解决:
//1、增加本地存储matches,针对每次反馈的matches比对,只实例化增加或者销毁不存在的
//2、或者每次增加或者减少比赛,可以尝试让服务端调用每个客户端执行
public void RefreshList(List<MatchInfoSnapshot> matches)
{
ClearList(); foreach(var match in matches)
{
var button = Instantiate(matchButton, transform);
button.GetComponent<MatchButton>().Initialize(match);
}
} private void ClearList()
{
foreach(Transform t in transform)
{
Destroy(t.gameObject);
}
}
}
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.Networking.Match;
using UnityEngine.UI; public class MatchButton : MonoBehaviour
{
private MatchInfoSnapshot match;
//private NetworkManager manager; public void Initialize(MatchInfoSnapshot match)
{
this.match = match; GetComponentInChildren<Text>().text = match.name;
GetComponent<Button>().onClick.AddListener(() =>
{
//manager.matchMaker.JoinMatch(match);
FindObjectOfType<CustomerUnetManger>().JoinMatch(match);
});
}
}
using UnityEngine;
using UnityEngine.UI; public class LogInfo : MonoBehaviour
{
public bool isDebug = true;
private Text log; public static LogInfo theLogger; public void Log(string info)
{
if(isDebug)
log.text += "\r\n" + info;
} private void Clear()
{
log.text = "Log:";
} void Start ()
{
theLogger = this;
log = GetComponent<Text>();
log.text = "Log:";
GetComponentInChildren<Button>().onClick.AddListener(Clear);
} }

NetworkManager网络通讯_NetworkManager(二)的更多相关文章

  1. NetworkManager网络通讯_破产版NetworkManager(五)

    根据对NetWorkServer 以及NetworkClient的理解,编写一个简易版的NetWork Manager.惯例全部代码放在最后 (一)NetWorkServer与NetworkClien ...

  2. NetworkManager网络通讯_问题汇总(四)

    此篇来填坑,有些坑是unet自身问题,而大部分则是理解不准确造成的(或者unity定义太复杂) 问题一: isLocalPlayer 值一直是false 出现场景:NetworkLobbyPlayer ...

  3. NetworkManager网络通讯_Example(一)

    ---恢复内容开始--- 用户手册,范例精讲. 用户手册上给出了一个简单的范例,并指出可以以此为基础进行相开发,再次对范例进行精讲.(NetworkManager对使用unity的轻量级游戏开发有很大 ...

  4. NetworkManager网络通讯_networkReader/Writer(六)

    unet客户端和服务端进行消息发送时可以采用上一节中方法,也可以直接用networkReader/Writer类进行发送 (一)服务端/客户端注册消息 ; m_Server.RegisterHandl ...

  5. NetworkManager网络通讯_NetworkLobbyManager(三)

    此部分可以先建立游戏大厅,然后进入游戏,此处坑甚多耗费大量时间.国内百度出来的基本没靠谱的,一些专栏作家大V也不过是基本翻译了一下用户手册(坑啊),只能通过看youtube视频以及不停的翻阅用户手册解 ...

  6. 网络通讯之Socket-Tcp(二)

    网络通讯之Socket-Tcp  分成2部分讲解: 网络通讯之Socket-Tcp(一): 1.如何理解Socket 2.Socket通信重要函数 3.Socket Tcp 调用的基本流程图 4.简单 ...

  7. 《连载 | 物联网框架ServerSuperIO教程》-4.如开发一套设备驱动,同时支持串口和网络通讯。附:将来支持Windows 10 IOT

    1.C#跨平台物联网通讯框架ServerSuperIO(SSIO)介绍 <连载 | 物联网框架ServerSuperIO教程>1.4种通讯模式机制. <连载 | 物联网框架Serve ...

  8. Windows 网络通讯开发

    Windows 网络通讯开发 一.Windows网络开发API 由于C++标准库中没有网络库,所以进行网络开发的时候要调用系统API.Windows通讯开发API包括以下几个基本函数及成员类型: 1. ...

  9. DIOCP网络通讯流程

    DIOCP 运作核心探密   原文连接: http://blog.qdac.cc/?p=2362 原作者: BB 天地弦的DIOCP早已经广为人知了,有很多的同学都用上了它,甚至各种变异.修改版本也出 ...

随机推荐

  1. com.rabbitmq.client.impl.ForgivingExceptionHandler.log:119 -An unexpected connection driver error occured

    在服务器上安装了一个RabbitMq,并新创建了一个用户授予了管理员角色,登录控制台查看一切正常,兴高采烈启动项目进行连接,结果一盆冷水下来,报如下错误: o.s.a.r.l.SimpleMessag ...

  2. Maven 梳理-安装配置

    项目构建过程包括[清理项目]→[编译项目]→[测试项目]→[生成测试报告]→[打包项目]→[部署项目]这几个步骤,这六个步骤就是一个项目的完整构建过程. 下载后解压   配置环境变量 F:\jtDev ...

  3. java8泛型

    目录 1,泛型中的相关操作符 2,泛型基本使用示例 3,通配符 3.1, T和?的区别 3.2,上下界通配符 4, 附加约束(&) ​ 泛型,也就是将类型参数化,然后在使用类或者方法的时候可以 ...

  4. Python基础(十四)

    今日主要内容 装饰器扩展 有参装饰器 多个装饰器装饰一个函数 递归 一.装饰器扩展 (一)含有参数的装饰器 先来回顾一下装饰器的标准模式 def wrapper(fn): def inner(*arg ...

  5. shell管道与重定向

    输出重定向 $ ls -l > lsoutput 这条命令将ls命令执行后的结果输入出到lsoutput文件中. 在linux shell中使用符号 > ,< 来完成输入输出的重定向 ...

  6. 一道短小精悍的JS小题目

    看到题目你是不是以为我在开车,没错,我就不承认,你能咋的,你瞅啥,别瞅我,瞅题 题目是这样式的 结果是啥呀,这里我就不买关子了,结果是undefined,相信基础好一点的大佬们一眼就能看出来,像我这种 ...

  7. ADB命令无法导出文件到物理机上处理办法

    因为想查看一下脚本生成的sqlite文件.就想导出文件,,结果导出adb pull命令一直报错.使用su也是错误的..最后发现adb pull 不能再adb的命令状态下执行.需要退出adb命令.然后直 ...

  8. A-02 梯度下降法

    目录 梯度下降法 一.梯度下降法详解 1.1 梯度 1.2 梯度下降法和梯度上升法 1.3 梯度下降 1.4 相关概念 1.4.1 步长 1.4.2 假设函数 1.4.3 目标函数 二.梯度下降法流程 ...

  9. 从键盘录入输入3 个数num1,num2,num3,按从大到小进行输出

    本题分别使用嵌套分支语句以及三目运算符来实现,两种方法,可以对比看看. import java.util.Scanner; /** * 从键盘录入输入3 个数a,b,c,按从大到小进行输出 * @au ...

  10. tp5中使用中间控制器代理路由,以避免创建过多的无用控制器方法

    在写项目的时候偶尔会加载一些不需要传递参数的静态视图,例如 class Index extends Common { public function index() { return $this-&g ...