NetworkManager网络通讯_问题汇总(四)
此篇来填坑,有些坑是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网络通讯_问题汇总(四)的更多相关文章
- NetworkManager网络通讯_破产版NetworkManager(五)
根据对NetWorkServer 以及NetworkClient的理解,编写一个简易版的NetWork Manager.惯例全部代码放在最后 (一)NetWorkServer与NetworkClien ...
- NetworkManager网络通讯_NetworkManager(二)
本文主要来实现一下自定UI(实现HUD的功能),并对Network Manger进行深入的讲解. 1)自定义manager 创建脚本CustomerUnetManger,并继承自NetworkMang ...
- NetworkManager网络通讯_Example(一)
---恢复内容开始--- 用户手册,范例精讲. 用户手册上给出了一个简单的范例,并指出可以以此为基础进行相开发,再次对范例进行精讲.(NetworkManager对使用unity的轻量级游戏开发有很大 ...
- NetworkManager网络通讯_NetworkLobbyManager(三)
此部分可以先建立游戏大厅,然后进入游戏,此处坑甚多耗费大量时间.国内百度出来的基本没靠谱的,一些专栏作家大V也不过是基本翻译了一下用户手册(坑啊),只能通过看youtube视频以及不停的翻阅用户手册解 ...
- NetworkManager网络通讯_networkReader/Writer(六)
unet客户端和服务端进行消息发送时可以采用上一节中方法,也可以直接用networkReader/Writer类进行发送 (一)服务端/客户端注册消息 ; m_Server.RegisterHandl ...
- 容联云通讯_提供网络通话、视频通话、视频会议、云呼叫中心、IM等融合通讯能力开放平台。
容联云通讯_提供网络通话.视频通话.视频会议.云呼叫中心.IM等融合通讯能力开放平台. undefined
- DIOCP网络通讯流程
DIOCP 运作核心探密 原文连接: http://blog.qdac.cc/?p=2362 原作者: BB 天地弦的DIOCP早已经广为人知了,有很多的同学都用上了它,甚至各种变异.修改版本也出 ...
- dicom网络通讯入门(2)
第二篇,前面都是闲扯 其实正文现在才开始,这次是把压箱底的东西都拿出来了. 首先我们今天要干的事是实现一个echo响应测试工具 也就是echo 的scu,不是实现打印作业管理么.同学我告诉你还早着呢. ...
- Socket网络通讯开发总结之:Java 与 C进行Socket通讯 + [备忘] Java和C之间的通讯
Socket网络通讯开发总结之:Java 与 C进行Socket通讯 http://blog.sina.com.cn/s/blog_55934df80100i55l.html (2010-04-08 ...
随机推荐
- JavaSE知识点总结(一)
第一章 课程介绍第二章 java语言概述 课时2:作业 1.常用软件分为那两类? 系统软件 应用软件 2.人机交互的两种方式是哪两种? 图形化界面 代码行命令 课时3:作业 1.java语言的特性有哪 ...
- Flume系列二之案例实战
Flume案例实战 写在前面 通过前面一篇文章http://blog.csdn.net/liuge36/article/details/78589505的介绍我们已经知道flume到底是什么?flum ...
- aapt的具体使用
一.什么是aapt: aapt Android Asset Packaging Tool android的一个资源打包工具 二.配置aapt路径: aapt这个工具,在sdk的build-tools下 ...
- 利用sqlalchemy 查询视图
这个问题 google 百度 中英文搜了一上午.最新的回答还是 7年前.最后自己靠着官方文档的自己改出来一个比较方便的方法 使用环境 python == 3.7.0 SQLAlchemy === 1. ...
- (java实现)单向循环链表
什么是单向循环链表 单向循环链表基本与单向链表相同,唯一的区别就是单向循环链表的尾节点指向的不是null,而是头节点(注意:不是头指针). 因此,单向循环链表的任何节点的下一部分都不存在NULL值. ...
- 编写shell脚本实现一键创建KVM虚拟机
shell脚本一键创建虚拟机 代码如下: #!/bin/bashname=$1 #把位置变量$1重新定义为name(创建虚拟机的名字)path1=/var/lib/libvirt/images/ #i ...
- python爬虫遇到会话存储sessionStorage
记录一次爬虫生成链接过程中遇到的sessionStorage存储数据 1.简介 sessionStorage 是HTML5新增的一个会话存储对象,用于临时保存同一窗口(或标签页)的数据,在关闭窗口或标 ...
- 第二篇:php开发工具
倍,这里为您介绍一些常用的工具. PHP IDE PHP IDE也不少,主要从几个方面进行筛选: 跨平台(能够同时在windows,mac或者ubuntu上面运行) 版本控制(SVN,GIT) 文件历 ...
- Vue入门教程 第二篇 (数据绑定与响应式)
数据绑定 Vue.js 的核心是一个允许采用简洁的模板语法来声明式地将数据渲染进 DOM 的系统: <div id="app"> {{ message }} </ ...
- Web性能优化:雅虎35条
对web性能优化,一直知道是个很重要的方面,平时有注意到,但是对于雅虎35条是第一次听说,查了一下,发现平时都有用过,只是没有总结到一块,今天就总结一下吧. 雅虎35条: 1.[内容]尽量减少HTTP ...