毕业设计的项目,需要用到手机作为控制端,这就需要用到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的一些过程的更多相关文章

  1. 学习 Git的使用过程

    原文链接: http://www.cnblogs.com/NickQ/p/8882726.html 学习 Git的使用过程 初次使用 git config --global user.name &qu ...

  2. linux内核学习之六 进程创建过程学习

    一 关于linux进程概念的补充 关于进程的基本概念这里不多说,把自己的学习所得作一些补充: 1. 在linux内核中,系统最多可以有64个进程同时存在. 2.linux进程包含的关键要素:一段可执行 ...

  3. 强化学习-MDP(马尔可夫决策过程)算法原理

    1. 前言 前面的强化学习基础知识介绍了强化学习中的一些基本元素和整体概念.今天讲解强化学习里面最最基础的MDP(马尔可夫决策过程). 2. MDP定义 MDP是当前强化学习理论推导的基石,通过这套框 ...

  4. go微服务框架go-micro深度学习 rpc方法调用过程详解

    摘要: 上一篇帖子go微服务框架go-micro深度学习(三) Registry服务的注册和发现详细解释了go-micro是如何做服务注册和发现在,服务端注册server信息,client获取serv ...

  5. 1.1(java学习笔记) 面向过程与面向对象

    面向过程思考时,我们会先思考具体的步骤,第一步走什么,第二步做什么. 比如电脑新建文件夹,第一步:打开电脑 第二步:按下鼠标右键. 第三步:找到新建选项 第四步:点击新建选项下的文件夹 c语言是典型的 ...

  6. 七天从零基础学习android(3)--实现过程

    首先这是我对自己编写程序的认识,要实现一个程序,根据之前编写C++的经验,要对所编写的软件有一个模糊的了解. 一个记账本软件,要实现的过程是,添加收支,显示本日,本月或本年的收支状态.然而基于是完全没 ...

  7. RocketMQ事务消息学习及刨坑过程

    一.背景 MQ组件是系统架构里必不可少的一门利器,设计层面可以降低系统耦合度,高并发场景又可以起到削峰填谷的作用,从单体应用到集群部署方案,再到现在的微服务架构,MQ凭借其优秀的性能和高可靠性,得到了 ...

  8. USB2.0协议学习笔记---USB工作过程(类的方法)

    前面学习了那么多的概念,这里需要记住一点分层概念即设备 ---> 配置 ---> 接口 ---> 端点,这种分层的概念结构 . 也可以理解为端点构成接口,接口组成配置,配置组成设备. ...

  9. 【Spring-web】RestTemplate源码学习——梳理内部实现过程

    2016-12-28 by 安静的下雪天  http://www.cnblogs.com/quiet-snowy-day/p/6228198.html  提示:使用手机浏览时请注意,图多费流量. 本篇 ...

随机推荐

  1. 小技巧:使用命令行打开vscode 以及 sublime 工具

    vscode手动打开vscode command + shift + p 打开命令面板(或者点击菜单栏 查看>命令面板)输入 shell 选择 install code command in P ...

  2. C++ 非白名单程序间接启动

    主要的思路是不能用不受信任的程序直接参与创建进程,而是间接启动目标进程.比如你可以把目标程序创建快捷方式,然后设置快捷键.然后向桌面发快捷键的按键消息,目标程序就会被桌面程序启动.

  3. SSM整合搭建过程中的一个怪异问题

    好久没有搭建框架了,昨天开始试图搭建一个SSM框架,各种配置文件搭建成功,服务器也启动正确,但是在运行过程中,发现总是不能获取JDBC,不能够创建连接池工厂,报错如下:网页报500错误码 SEVERE ...

  4. Redis集群环境之linux搭建多机版---已完结,跟着一步一步来你就可以集群成功

    上一篇踩着各种坑写了Redis集群环境之linux搭建单机版,这一篇准备就多机版集群进行搭建,主要目的一来是在上一篇的基础上进行精华提粹总结,二来是把单机版与多机版的区别进行记录. 首先软硬件环境: ...

  5. js里事件传播流程

    Javascript与HTML之间的交互是通过事件实现的. 事件,就是文档或浏览器窗口中发生的一些特定的交互瞬间. 可以使用侦听器来预定事件,以便事件发生时执行相应代码. 事件流 JS事件流最早要从I ...

  6. tensorflow学习笔记(三)常用函数

    上一篇简单介绍了tensorflow的基本操作,这一篇介绍一些常用的函数. tf.constant() tf.constant ( value , dtype = None , shape = Non ...

  7. redis常用的命令行以及操作

    redis常用的命令行以及操作 转载酱紫人的理直气壮 最后发布于2018-07-30 17:00:41 阅读数 805  收藏 转载地址:https://blog.csdn.net/li_lening ...

  8. 132-PHP子类和父类同名函数的调用

    <?php class father{ //定义father类 public function cook(){ return '烹饪'; } } class son extends father ...

  9. 八、React实战:可交互待办事务表(表单使用、数据的本地缓存local srtorage、生命同期函数(页面加载就会执行函数名固定为componentDidMount()))

    一.项目功能概述 示例网址:http://www.todolist.cn/ 功能: 输入待做事项,回车,把任务添加到 [正在进行] [正在进行] 任务,勾选之后,变成已[经完成事项] [已完成事务], ...

  10. grep -q

    grep -q用于if逻辑判断      安静模式,不打印任何标准输出.如果有匹配的内容则立即返回状态值0. grep -q的用法 #  if  grep -q hello a.txt ; then ...