注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

刘邓

每天收获一点点-目标:富足

 
 
 

日志

 
 

C# Unity远程调试器  

2013-03-03 18:01:59|  分类: 总结类 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
开发环境:Unity,C#,VS,MonoDevelop
这周接到一个需求:
建立一个服务器,建立到客户端(手机,PC版,网页版)的连接,来进行远程调试。
调试的内容包括至少包括:
内存:1.所占总内存2.GC内存
3.获取指定Object(包括 GameObject,各种Component)所消耗内存
数量:1.GameObject的数量,Component数量 2.指定Object的数量
内容:1.Object的类型 2.Component的属性列表和属性值(向下递归)
杂项:1.考虑设定客户端主动获取镜像(相当于某一帧状态下的客户端运行拷贝)的条件:低于XX帧数;GC超过XX值;GameObject和Component数量差值大于临界值等。
——————————————————————————————————————
这里做个反省:接到需求首先应该进行的是可行性分析,分析指定的功能组件能否实现,如能否获取当前运行状态下的GameObject和Component,如果能获取,能获取到何种程度。以此来绝对接下来的系统还是否有做下去的必要。但是我却上来想着把底层的网络部分搞好,再去考虑C#反射获取对象的各个属性,这是不对的,以后工作中要注意。
———————————————————————————————————————
首先考虑的网络实现是借助C#Unity的Network类来进行操作,下面是对学习的Network及相关的笔记:
服务器端:
1.对指定的GameObject挂上NetworkView的组件
2.Network.InitializeServer;可以添加事件的响应函数:玩家连接OnPlayerConnected,玩家断开连接等
3.只试验了RPC功能(没有试验状态同步),在客户端,服务设置需要的RPC函数,用networkView.RPC()函数就可以调用指定客户端/服务器上的RPC函数,消息传递则可以作为RPC函数的参数
PS:此方案被废弃,原因是参数限制太大,而我们的要传递的结构比较复杂:int, float, string, NetworkPlayerNetworkViewIDVector3 and Quaternion,后来考虑过用状态同步方式,而状态同步的主要消息传递函数OnSerializeNewworkView()的bitstream支持序列化的参数类型也是上面几个。
———————————————————————————————————————
网络部分采用传统的Socket方式,数据传输用C#原生的对象序列化:BinaryFormater
服务器:
一个主处理线程(Update就是MonoBehavior的更新函数,也就是Unity主线程)
一个接受客户端请求线程
每个连接建立一个接受线程,每个连接有一个接收队列(添加在接受线程和移除在主处理线程,所以加锁)
一个发送线程,和一个共享的发送队列(同样要加锁)
协议部分:开头四个字节表示消息长度,第五个字节表示ActionType,根据枚举的ActionType回调注册的托管函数。
客户端:
一个主处理线程(同样的客户端主线程)
一个接受线程
一个发送线程
———————————————————————————————————————
C#反射:
1.System.Reflection.FieldInfo获取类的自定义属性字段(不包括基础图上层中自定义字段 )
2.System.Reflection.PropertyInfo获取从系统Object为起点一路继承下来的属性字段(不包括基础图中上层自定义字段)
3.System.Reflection.MethodInfo获取成员函数信息(包括自定义,和继承的)
4.isPrimitive判断类型是否为系统类型
5.BindingFlags:
Instance 指定实例成员将包括在搜索中(我表示无法理解,且此flag是必需的)
Static 静态成员 Public 公共成员 NoPublic 私有和保护 DeclaredOnly只包含当前层的,继承的不算,以上的Flag都可以组合使用。
——————————————————————————————————————
其他:
1.递归“拍下”客户端运行实况,数据量太大,不可能一次性发送。对此抽象出来2个类:
一个GameObjectInfo:
静态:一个hashCode到object的map:GuidToObjectMap,所有的GameObjectInfo和ComponentInfo在构造函数中都会将自身和其对应的hashCode添加到此map中。
主要包含子GameObjectname和其hashCode的map,这样服务器监控者如果想继续深入查看列表中对应名称的GameObjectInfo内容,则将此GameObject的hashCode发送到客户端,然后客户端再将静态GuidToObjectMap找到的object序列化后发送给服务器
同理还有一个ComponentInfo的map,实现原理和上面一致
另外一个类为ComponentInfo:
包含此Component的属性列表,及其对应值(如果是primitive类型的属性,则将字段value设置上,否则递归下去,将递归出来的ComponentInfo添加到父节点上),服务器如果想查看某个ComponentInfo同样将其对于的hashCode发到客户端,然后取出GuidToObjectMap中对于的Object序列化后发到服务器。
代码质量:
1.对于大于一个地方需要用到的代码段,尽量以函数方式包装起来。
2.保持变量和函数命名的规范和统一
3.注释简洁明了
4.函数的参数设计要尽量简单。
        


  评论这张
 
阅读(822)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017