此篇来填坑,有些坑是unet自身问题,而大部分则是理解不准确造成的(或者unity定义太复杂)

问题一: isLocalPlayer 值一直是false

出现场景:NetworkLobbyPlayer中重写 OnClientEnterLobby()方法时出现(public override void OnClientEnterLobby()),当时想法是当玩家进入lobby后对local Player进行个性化设置,但返回结果一直是false。此问题在其他情况可能也会出现。

解决方案:此问题主要是对isLocalPlayer,isServer以及isClient定义不清楚。isServer:在服务端的活动的player,此值均为true,即不管是server端StartHost时自己建立的client还是Server Spawn产生,只要在服务端显示,此值均为true。isClient:由Server端spawn产生,并作为client运行的,此值均为true,即只要是Spawn产生的,不管是在服务端还是在客户端,此值均为true。所以服务端存在的player,isServer和isClient均为true,客户端isclient均为true,isServer均为false。(isServer与isClient并没有对立关系)。isLocalPlayer是生成的玩家可以控制的player,不管是服务端(如果服务端也有玩家)还是客户端均只有一个player的isLocalPlayer值为true。isLocalPayer在执行OnStartLocalPlayer回调时赋值为true,即生成本地的player时赋值,而OnClientEnterLobby回调时只是数据层面已经客户端连接进来,但是还没有建立client的gameobject,所以此时isLocalPlayer并未赋值(默认false)。而且只有本地

玩家的player是Create产生的,先回调OnClientEnterLobby,后回调函数OnStartLocalPlayer,而且其他玩家(敌人)则是有服务端Spawn产生的,只调用回调OnClientEnterLobby。

问题二: Server disconnect due to error:timeout

出现场景:当Server运行时,client断开时出现(第一次断开不会出现,第二次断开以及以后均会出现)

解决方案:无法解决,但不影响运行。谷歌很多此,在unity论坛中有unity人员(自己号称)unet自身bug,此问题类似于tcp或者udp编程时,客户端主动断开连接,而服务端虽然接受到了断开的消息(甚至没有接收到),但依然接受下一条消息,此时报错(如果有人看过作者写过的一个tcpServer,会看到类似问题)。当然对于unet来说此问题可能涉及到的东西比较复杂,号称已经解决,但是在后续版本中一直存在,笔者为unity2017,仍存在此问题,并未下载补丁进行尝试,谷歌出来的此问题来源如下,如果不想出现此问题可以在重写OnServerDisconnect时不调用基函数,只添加NetworkServer.DestroyPlayersForConnection(conn)即可。

public virtual void OnServerDisconnect(NetworkConnection conn)
{
NetworkServer.DestroyPlayersForConnection(conn);
if (conn.lastError != NetworkError.Ok)
{
if (LogFilter.logError)
{
Debug.LogError("ServerDisconnected due to error: " + conn.lastError);
}
}
}

问题三: Client disconnect due to error:timeout

出现场景:当在lobby场景中调用DropConnection断开玩家与Server的连接时出现

解决方案:无法解决,但不影响运行。谷歌很多此,此问题也没有很好的得到解决,有点类似与问题三。

问题四: A connection has already set as ready....

出现场景:远程客户端调用RemovePlayer()退出游戏又重新加入时出现。在OnClientSceneChanged的base中会调用AddPlayer,也会出现此问题(目前选择直接暴力注释掉base方法)

解决方案:unity远程客户端和服务端建立连接时先建立NetworkConnection,然后分别建立服务端和客户端的游戏物体,所以调用removePlayer方法时只是在clientscene中removePlayer,并没有断开连接,所以在重新加入游戏时会出现此问题(即本身的connection还存在),此问题不影响运行,但是不确定会有其他隐患,多以在上一篇中远程客户端断开连接时采用matchmaker的DropConnection方法(调用此方法时会自动移除服务端和游戏端的游戏物体),但此方法又会引发问题三,可以采用connectionToServer进行解决,具体看问题六。

问题五: Local Connection already exists 以及ClientScene::AddPlayer: playerControllerId of 0 already in use

出现场景:建立游戏的主机销毁游戏时出现

解决方案:主机建立游戏,如果想要销毁游戏需要三步,第一步销毁player(remove Player方法),第二部断开connection(可以理解为销毁游戏即destroy Match),第三部StopHost。第一步时为了移除clientScene中的player,如果缺少则会引发ClientScene::AddPlayer: playerControllerId of 0 already in use问题。如果缺少第二部则会引发问题四,而且游戏不会销毁。如果缺少第三部,怎会引发 Local Connection already exists,因为不管是否销毁游戏,建立游戏主机的本机player即使服务端player,又是client端player,所以localconnection会一直存在,只有StopHost才会断开此本地连接。

问题六:connectionToClient以及connectionToServer应用

出现场景:此问题设计到离开游戏的定义。以魔兽争霸(frozenstone暴露年龄了)为例,局域网建立一个游戏,局域网内其他玩家加入此游戏,那么客户端(加入游戏的玩家)只能自己离开游戏,所以此时对应的问题四出现的场景即加入游戏的玩家自己离开游戏。建立游戏的玩家可以选择自己退出游戏(销毁游戏)也可以选择将不顺眼的玩家踢出,前者自己退出游戏对应问题五场景。那么踢出其他游戏时就是对应此问题。即要想踢出玩家,只要断开此玩家有服务端的连接即可。

解决方案:connectionToClient定义为服务端与客户端的连接,但是只在服务端有效(只有在服务端此connectionToClient变量才有效)。所以此情况下只要调用connectionToClient的Disconnect方法并dispose即可。相反,connectionToServer定义为仍然为服务端与客户端的连接,但是此方法只在local client有效,所以问题四也可以调用connectionToServer的Disconnect方法并dispose(此方法为测试,但从释义上将可行,并且应该可以避免问题四和问题三)

问题七:drop Connection与destroyconnection时场景重新加载

出现场景以及解决方案:第一次dropconnection时场景会重新加载(并非在dropconnection的回调中调用重新加载,二十直接在dropconnection方法中就重新加载),之后再次调用则不会重新加载,目前看不到内部代码,所以只能避免使用drop Connection,所以问题四中离开游戏时可以使用connectionToServer进行尝试。

destroyconnection是每次调用都会加载场景,其实可以理解,每次重新创建游戏时回到最初也是可以接受的,不过要想不重新加载只能查看源码了。

问题八:DontDestroyOnLoad问题

出现场景以及解决方案:在上一篇中开头讲过不要在自定义的LobbyManager中添加DontDestroyOnLoad,如果反复进行自身场景的加载就会一直不停的添加LobbyManager,即没加载一次都会生成一个新的LobbyManager,而原来的又不会销毁掉。而NetworkManager中已经存在,所以不要直接调用了,很多视频demo中都加了此语句,但是他们那些demo都是一根筋跑到底,没有出现重新加载的问题,所以此处要慎重,实现像调用可以看http://www.xuanyusong.com/archives/2938。而且如果添加了DontDestroyOnLoad还可能会出现中间

LobbyManager丢失的情况,之前做一个项目时,有一个插件也用到此方法,但是一重新加载就导致DontDestroyOnLoad对应的组件(脚本)获取不到,但是editor中查看此组件(脚本)时存在的,所以慎重调用。

问题九:超上限加入游戏

出现场景以及解决方案:当游戏设置玩家为2,即使人数已满,但仍然可以加入此游戏,但是加入后的游戏玩家显示会有问题,所以只能在加入游戏前自己做判断,不能靠unet自己处理。

问题十:ready后自动开始游戏

出现场景以及解决方案:当当前游戏中的所有玩家均ready后立马开始游戏,即当前只有一个玩家,没有达到游戏玩家数,若此玩家发送了准备(sendreadytobeginMessage),则服务端调用OnLobbyServerPlayersReady,并在其base方法中立马开启游戏,所以此处不能调用其base方法。

PS:到此为止,踩了很多坑,目找时间看看networkmanager源码,unet的思路很不错,如果发展好了将会使多人在线游戏开变得更加简单。他与传统的客户端服务端分离不同(即客户端与服务端是不同的类),他揉合在一起,但又设定好了不同的角色与权限,虽然理解起来比较费解,但是应用起来确实方便。

NetworkManager网络通讯_问题汇总(四)的更多相关文章

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

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

  2. NetworkManager网络通讯_NetworkManager(二)

    本文主要来实现一下自定UI(实现HUD的功能),并对Network Manger进行深入的讲解. 1)自定义manager 创建脚本CustomerUnetManger,并继承自NetworkMang ...

  3. NetworkManager网络通讯_Example(一)

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

  4. NetworkManager网络通讯_NetworkLobbyManager(三)

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

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

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

  6. 容联云通讯_提供网络通话、视频通话、视频会议、云呼叫中心、IM等融合通讯能力开放平台。

    容联云通讯_提供网络通话.视频通话.视频会议.云呼叫中心.IM等融合通讯能力开放平台. undefined

  7. DIOCP网络通讯流程

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

  8. dicom网络通讯入门(2)

    第二篇,前面都是闲扯 其实正文现在才开始,这次是把压箱底的东西都拿出来了. 首先我们今天要干的事是实现一个echo响应测试工具 也就是echo 的scu,不是实现打印作业管理么.同学我告诉你还早着呢. ...

  9. Socket网络通讯开发总结之:Java 与 C进行Socket通讯 + [备忘] Java和C之间的通讯

    Socket网络通讯开发总结之:Java 与 C进行Socket通讯 http://blog.sina.com.cn/s/blog_55934df80100i55l.html (2010-04-08 ...

随机推荐

  1. asp.netcore 3.0 Docker Nginx(震惊,原来docker是这样的!)

    引言 Docker发布于2013年,Docker是dotCloud公司创始人在法国期间发起的一个公司内部项目,他是dotCloud多年云技术的一个革新.Docker在容器基础上进行了一步的封装,从网络 ...

  2. Hadoop点滴-HDFS文件系统

    1.HDFS中,目录作为元数据,保存在namenode中,而非datanode中 2.HDFS的文件权限模型与POSIX的权限模式非常相似,使用  r  w  x 3.HDFS的文件执行权限(X)可以 ...

  3. springmvc(二)

    请求信息转换 异步发送表单数据到JavaBean,并响应JSON文本返回 操作步骤:(1)加入Jackson2或fastjson框架包,springmvc默认支持Jackon2,不需要做任何操作,而f ...

  4. 2017CCSP-01 五子棋 简单模拟

    题面和数据 对于每个空格,先定义一个变量cnt=0,表示空格填充后对五子数量的变化,四个方向进行两边搜索,设对于每个方向连续的白棋子分别为\(wa\),\(wb\),有以下几种情况. \(wa> ...

  5. Logrotate配置

    目录 Logrotate配置 参考 Logrotate Description Logrotate Configuration Logrotate配置

  6. 完美实现保存和加载easyui datagrid自定义调整列宽位置隐藏属性功能

    需求&场景 例表查询是业务系统中使用最多也是最基础功能,但也是调整最平凡,不同的用户对数据的要求也不一样,所以在系统正式使用后,做为开发恨不得坐在业务边上,根据他们的要求进行调整,需要调整最多 ...

  7. 安卓tab,viewPaper以及frament的使用

    安卓TabLayout,ViewPager以及fragment的使用 Demo效果 首先先说一下这个demo的最终效果吧: 项目地址:https://github.com/xiaohuiduan/fr ...

  8. 注册中心nacos完整部署及与eureka区别

    1. 场景描述 nacos最近用的比较多,介绍下nacos及部署吧,刚看了下以前写过类似的,不过没写如何部署及与eureka区别,只展示了效果,补补吧. 2.解决方案 2.1 nacos与eureka ...

  9. 记一次客户DB CPU短时间内冲高至99%处理

    问题背景: 客户反映DB CPU短时间内冲高,查询变得缓慢,记录此背景下的处理方式 1> 查看系统负载及相关sql 2> 查看相关sql的执行计划 3> 想看相关sql的执行计划是否 ...

  10. 【NOIP2016】蚯蚓

    Description 本题中,我们将用符号 ⌊c⌋表示对 cc 向下取整,例如:⌊3.0⌋=⌊3.1⌋=⌊3.9⌋=3. 蛐蛐国最近蚯蚓成灾了!隔壁跳蚤国的跳蚤也拿蚯蚓们没办法,蛐蛐国王只好去请神刀 ...