此篇来填坑,有些坑是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. Java 基础篇之类与对象

    类与对象 类.对象和引用的关系 类和对象的关系 类是对象的模版,对象是类的一个实例,一个类可以有很多对象 一个Java程序中类名相同的类只能有一个,也就是类型不会重名 一个对象只能根据一个类来创建 引 ...

  2. Redis数据库安装与配置调试

    主要培养自我对Redis数据库安装能力, 并且进行个性化的数据库配置.掌握本实验的重点,即在于数据库的安装与启动参数的配置.同时,理解NOSQL数据库的体系结构. ①下载Redis安装包进行数据库平台 ...

  3. 使用webgl(three.js)搭建3D智慧园区、3D大屏,3D楼宇,智慧灯杆三维展示,3D灯杆,web版3D,bim管理系统——第六课

    前言: 今年是建国70周年,爱国热情异常的高涨,为自己身在如此安全.蓬勃发展的国家深感自豪. 我们公司楼下为庆祝国庆,拉了这样的标语,每个人做好一件事,就组成了我们强大的祖国. 看到这句话,深有感触, ...

  4. Two progressions CodeForce 125D 思维题

    An arithmetic progression is such a non-empty sequence of numbers where the difference between any t ...

  5. C语言I博客作业02

    这个作业属于那个课程  C语言程序设计I 这个作业要求在哪 https://edu.cnblogs.com/campus/zswxy/CST2019-3/homework/8656 我在这个课程的目标 ...

  6. 基于elasticsearch的自定义业务告警的设计思路

    A系统与B系统之间有很多接口交互,但是有一段时间接口经常报错,作为开发如果不能第一时间知道问题且及时解决的话就会收到业务投诉,当月绩效凉凉. 如果你也有这种场景,那么你就需要一个及时告警的功能. 实现 ...

  7. mybatis执行过程及经典面试题

    Mybatis执行流程 mybatis中xml解析是通过SqlSessionFactoryBuilder.build()方法. 初始化mybatis(解析xml文件构建成Configuration对象 ...

  8. Java 学习笔记之 Daemon线程

    Daemon线程: 线程: 用户线程 守护线程 守护线程是一种特殊的线程,在进程中不存在非守护线程了,则守护线程自动销毁. public class DaemonThread extends Thre ...

  9. 快学Scala 第十八课 (trait多继承)

    trait多继承: trait的继承并不像类拥有相同的含义!在下面这个例子中,如果还是运用类的继承的思想,那么运行结果将是什么也没有. trait Logged { def log(msg: Stri ...

  10. redis在mac上的下载安装

    redis官网下载压缩包: 在终端进入下载后的目录,然后: 解压:tar zxvf redis-5.0.5.tar.gz 移动到:sudo mv redis-5.0.5 /usr/local 切换到: ...