学习Unet的一些过程
毕业设计的项目,需要用到手机作为控制端,这就需要用到Unity的网络模块。
因为只会设计到几个简单的按钮命令,所以不打算做多么复杂的功能,一开始打算用C#的Socket编程,但是考虑到多线程的关系觉得以后跟UI结合起来处理会比较麻烦,机智的我决定使用Unity提供的Unet网络模块。不需要太麻烦,只需要cs之间发送消息就行。
一开始我感觉自己掉进了一个坑,网上关于Unet的例子不要太少,而且很多都是基于多人游戏的。最无语的一点就是里面最牛的Commands和ClientRpc的远程调用命令以及各种变量同步只支持同一对象的不同实例间调用,简单点来说,就是客户端和服务器必须是同一个安装包,他俩只是打开方式不一样。但是我只是想做一个控制器作为客户端而已呀。但是我还是坚信,如此牛x的网络模块,肯定会支持我想要的这种傻x通信的。
我仔细看了Unity所有的关于Network的组件。最后将目标锁定在了NetworkManager上。接下来就是去看NetworkManager的API啦,果然,一拉下来我就知道没有错了

在Public Functions里存在许多On开头的方法,对Unity稍微熟悉一点的都知道以On开头的是Unity提供的回调函数,用于处理事件。同时也找到了StartClient、Host、Server这些方法。找到了常用的操纵方法和回调函数,接下来就是要找发送和接收消息的对象了。但是我没有丝毫头绪。我决定先将客户端和服务器连接成功再说。于是,我先引用到NetworkManager的对象,在手机端调用StartClient方法,在电脑端调用StartSever方法。发现二者能连接成功。
接下来就是处理一些连接事件了,在Scripting API文档里看NetworkManager类的Description。这里用一段简洁的代码清楚的介绍了如何使用这些连接事件

是的,只需要写一个类继承NetworkManager类。就可以很容易的重写回调函数,自定义连接事件了。何止爽歪歪。
然后我将原来添加的NetworkManager组件删掉,新建一个类并继承自NetworkManager。重写了一些需要用到的回调方法。完美搞定。
现在能连接成功,并且也能处理一些连接事件了,接下来就是cs之间收发消息了。根据经验,cs之间收发消息应该是依靠某种对象调用Send方法和Receive方法。继续查阅API发现有这么五个可能会用到的类NetworkServer、NetworkClient、NetworkReader、NetworkWriter、NetworkConnection。因为我在NetworkServer、NetworkClient、NetworkConnection都找到了与send有关的方法;而NetworkReader、NetworkWriter一看就知道是一个读一个写。但是却没有在NetworkServer、NetworkClient、NetworkConnection这三个类找到任何与Receive有关的方法,就觉得很奇怪。按理说有了NetworkReader、NetworkWriter就能实现我想要的功能了,但是我发现回调函数都会传递一个NetworkConnection对象,所以我还是希望直接使用NetworkConnection类,于是抛弃了Reader和Writer,把重点放在了NetworkConnection类。继续看API… 仔细查看了NetworkConnection的所以方法的介绍,发现有这么一个方法public void RegisterHandler(short msgType, Networking.NetworkMessageDelegate handler) 才意识到原来这里使用的是观察者模式。再进NetworkMessageDelegate看看这个委托的声明格式。我只需要自定义一个与NetworkMessageDelegate相同格式的方法。看看NetworkMessageDelegate的声明格式:
public delegate void NetworkMessageDelegate(Networking.NetworkMessage netMsg)。这里又涉及到了一个类: NetworkMessage,依稀中记得NetworkConnection的send方法也需要传递一个NetworkMessage对象。说明我的方向没有错,NetworkConnection的消息传递是通过NetworkMessage类来封装的。过程应该是非常明朗的。先构造一个NetworkMessage对象,将这个对象通过send发送出去,在另一端用注册的方法接收NetworkMessage对象,最后解析成自己需要的信息。那么接下来最后一步--了解NetworkMessage类,继续API…
接下来遇到一个比较棘手的问题—我找不到构造NetworkMessage对象的方法,API里没有提供构造函数,也没有找到任何有用的静态方法。打算将希望寄托到他的父类,在vs里双击选中NetworkMessage,F12转到定义。才发现他没有父类,简直握草了,似乎走进了死胡同。这时只有拿出终极武器了,百度一下… 直接搜索NetworkMessage。在这篇文章中找到了方法。仔细研究了一下,发现和我的思路几乎一样。
好了,最后来总结一下过程,先说服务器端:
1、 写一个Sever类,继承自NetworkManager。把这个类挂在一个空物体上,并在Inspector面板设置好参数
2、 写按钮点击一个事件,调用StartServer方法
3、 使用override关键字重写一些on开头的网络事件方法
4、 写一个sendMsg的方法,在方法体内调用NetworkConnection的send方法
5、 写一个public void XXX(NetworkMessage netMsg)这种声明方式的方法,处理收到的消息
6、 找一个合适的时机,调用NetworkConnection的RegisterHandler方法,将第五步定义的方法注册进来
客户端:
1、 写一个Client类,继承自NetworkManager。把这个类挂在一个空物体上,并在Inspector面板设置好参数(注意,客户端的NetworkAddress应该填写服务器端的IP,注意保持端口一致)
2、 写按钮点击一个事件,调用StartClient方法
3、 使用override关键字重写一些on开头的网络事件方法
4、 写一个sendMsg的方法,在方法体内调用NetworkConnection的send方法
5、 写一个public void XXX(NetworkMessage netMsg)这种声明方式的方法,处理收到的消息
6、 找一个合适的时机,调用NetworkConnection的RegisterHandler方法,将第五步定义的方法注册进来
学习Unet的一些过程的更多相关文章
- 学习 Git的使用过程
原文链接: http://www.cnblogs.com/NickQ/p/8882726.html 学习 Git的使用过程 初次使用 git config --global user.name &qu ...
- linux内核学习之六 进程创建过程学习
一 关于linux进程概念的补充 关于进程的基本概念这里不多说,把自己的学习所得作一些补充: 1. 在linux内核中,系统最多可以有64个进程同时存在. 2.linux进程包含的关键要素:一段可执行 ...
- 强化学习-MDP(马尔可夫决策过程)算法原理
1. 前言 前面的强化学习基础知识介绍了强化学习中的一些基本元素和整体概念.今天讲解强化学习里面最最基础的MDP(马尔可夫决策过程). 2. MDP定义 MDP是当前强化学习理论推导的基石,通过这套框 ...
- go微服务框架go-micro深度学习 rpc方法调用过程详解
摘要: 上一篇帖子go微服务框架go-micro深度学习(三) Registry服务的注册和发现详细解释了go-micro是如何做服务注册和发现在,服务端注册server信息,client获取serv ...
- 1.1(java学习笔记) 面向过程与面向对象
面向过程思考时,我们会先思考具体的步骤,第一步走什么,第二步做什么. 比如电脑新建文件夹,第一步:打开电脑 第二步:按下鼠标右键. 第三步:找到新建选项 第四步:点击新建选项下的文件夹 c语言是典型的 ...
- 七天从零基础学习android(3)--实现过程
首先这是我对自己编写程序的认识,要实现一个程序,根据之前编写C++的经验,要对所编写的软件有一个模糊的了解. 一个记账本软件,要实现的过程是,添加收支,显示本日,本月或本年的收支状态.然而基于是完全没 ...
- RocketMQ事务消息学习及刨坑过程
一.背景 MQ组件是系统架构里必不可少的一门利器,设计层面可以降低系统耦合度,高并发场景又可以起到削峰填谷的作用,从单体应用到集群部署方案,再到现在的微服务架构,MQ凭借其优秀的性能和高可靠性,得到了 ...
- USB2.0协议学习笔记---USB工作过程(类的方法)
前面学习了那么多的概念,这里需要记住一点分层概念即设备 ---> 配置 ---> 接口 ---> 端点,这种分层的概念结构 . 也可以理解为端点构成接口,接口组成配置,配置组成设备. ...
- 【Spring-web】RestTemplate源码学习——梳理内部实现过程
2016-12-28 by 安静的下雪天 http://www.cnblogs.com/quiet-snowy-day/p/6228198.html 提示:使用手机浏览时请注意,图多费流量. 本篇 ...
随机推荐
- CAN分帧接收实现
该版本程序实现了上电后先发送MACID检测功能,如果网络上有应答.则一直进行死循环,直到用户更改了本机的ID地址 才可以跳出循环体. 本单片机设置为双滤波 ,使目标地址为0X1F 实现了建立连接命令 ...
- Gym - 101158C Distribution Center
题意:n个传送带,传送带i运送编号为i的物品,机器人可以负责把传送带i上的物品放到传送带i + 1上,也可以把传送带i + 1上的物品放到传送带i上,机器人分布在传送带上x轴的不同位置,问每个传送带最 ...
- pip制作离线安装包
有的电脑无法连接外网(金融行业你懂的),上网下载包又下载不到 anaconda安装一个包(联网情况下)很简单 pip install python-docx 如何把python-docx做成离线包安装 ...
- 微信小程序如何刷新当前界面
在微信小程序开发的过程中,在一个页面中对数据操作之后我们大多数时间都需要刷新一下当前界面以把操作之后的结果显示出来,但是如何在执行操作后进行本页面的刷新就成了一个问题很大但是很需要的操作.下面介绍一下 ...
- Pip,pywin32,whl文件下载网址,mayavi安装包,PyQt5安装,PyMuPDF安装等注意事项
(1)pip安装的包不一定是用户想要的位置,此时可以用 -t 选项来指定位置. 例如目标位置是/usr/local/lib/python2.7/site-packages/ ,要安装xlrd 这个包 ...
- 吴裕雄 Bootstrap 前端框架开发——Bootstrap 字体图标(Glyphicons):glyphicon glyphicon-qrcode
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name ...
- P1031 查验身份证
转跳点:
- Java中的Math.abs()
Math.abs(n):对int.long.float.double类型的数取绝对值 其中 int 类型的数取值范围是 -2^31——2^31-1(-2147483648 ~ 2147483647) ...
- 19 01 15 js 尺寸相关 滚动事件
尺寸相关.滚动事件 1.获取和设置元素的尺寸 width().height() 获取元素width和height innerWidth().innerHeight() 包括padding的width和 ...
- Unity 可重复随机数
出处 https://blogs.unity3d.com/cn/2015/01/07/a-primer-on-repeatable-random-numbers/ (英文原版) http://ww ...