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 ...
随机推荐
- Django REST Framework序列化器
Django序列化和json模块的序列化 从数据库中取出数据后,虽然不能直接将queryset和model对象以及datetime类型序列化,但都可以将其转化成可以序列化的类型,再序列化. 功能需求都 ...
- 2019-2020-1 20199303<Linux内核原理与分析>第二周作业
2019-2020-1 20199303第二周作业 1.汇编与寄存器的学习 寄存器是中央处理器内的组成部份.寄存器是有限存贮容量的高速存贮部件,它们可用来暂存指令.数据和位址.在中央处理器的控制部件中 ...
- Windows Terminal 安装及美化
windows terminal 是今年微软Build大会上推出的一款的全新终端,用来代替cmder之类的第三方终端.具有亚克力透明.多标签.Unicode支持(中文,Emoji).自带等宽字体等这些 ...
- Spark 学习笔记之 Streaming Window
Streaming Window: 上图意思:每隔2秒统计前3秒的数据 slideDuration: 2 windowDuration: 3 例子: import org.apache.kafka.c ...
- Scala 学习笔记之函数(2)
class OldStudent extends Student { def filterName(s: String, f: String => String) = { if (s != nu ...
- redhat 7系统服务工具-systemctl
- 《构建之法》项目管理&典型用户和场景
项目管理 PM的能力要求和任务: 1.观察.理解和快速学习能力 2.分析管理能力 3.一定的专业能力 4.自省的能力 在一个项目中,PM的具体任务: 1.带领团队形成团队的目标/远景,把抽象的目标 ...
- 【CPU】解决打开360或者Chrome浏览器CPU占用过高
cmd 运行: RD /s /q "%USERPROFILE%\AppData\Roaming\Microsoft\Protect"
- Docker service update更新不成功的问题
一.基本信息 1.Docker版本 [root@ip---- ~]# docker --version Docker version , build a872fc2f86 2.系统版本 [root ...
- XCTF-web2
这种题目是比较简单地..直接写个小脚本就行了2333 <?php $a=" a1zLbgQsCESEIqRLwuQAyMwLyq2L5VwBxqGA3RQAyumZ0tmMvSGM2Z ...