注:以下文章是我收录两年前记录的csDN博客。

一、前言

1、有些人其实会觉得Unity3D用到的.NET是2.0的,其实不然;Unity3D有用到.NET3.5,为什么说Unity用到的是3.5呢,从一个很常用却很重要的一个命名空间说起,他就是System.Linq命名空间,这个命名空间是.NET3.5重要的一次改革和核心部分(本命名空间与该文章并没有什么很大的联系,只是提下而已)。至于为什么显示成2.0我也不是很清楚,可能只支持部分3.5吧,不过对我们来说关系并不是很大。只要支持Linq就可以了。

2、前提工作:虚拟串口和Unity3D切换成.NET。

2.1 虚拟串口的创建,可以从网上下载一个创建虚拟串口的软件,比如“VSPD虚拟串口”,还是挺好用的,不过因为我做Unity3D的虚拟串口工作,所以根据VSPD专门写了一个创建虚拟串口的程序(暂时不提供)。在创建虚拟串口的时候注意一个很重要的问题,就是尽量创建串口号大于10的,比如COM10、COM11甚至夸张点COM100等,为什么要这样子,后面我会介绍Unity3D打开串口时,串口号大于10时,打开串口方式与.NET打开串口的方式是不一样的。

2.2 将Unity3D的API平台切换成.NET2.0。如何切换“Edit–project Setting–Player–Other Setting –Api Compatibility level”。在这里将“.NET2.0 Subset”切换为“.NET2.0”。

unity串口控制界面(Unity3D内部串口通信与Winform的实现和异常问题)(1)

2.3 Unity的目标平台一定要切换为Windows平台,否则是其他平台会报错误,本人就是深有体会,针对这个问题找原因找了很久,什么百度、谷歌、论坛都查阅了,最后还是无意中自己发现解决的了。

unity串口控制界面(Unity3D内部串口通信与Winform的实现和异常问题)(2)

切换为Web平台时报的错误

unity串口控制界面(Unity3D内部串口通信与Winform的实现和异常问题)(3)

3、Unity的串口与.NET的串口对象参数有些不一样,比如在Unity3D中打开串口,SerialPort对象的属性、方法、事件等要比.NET SerialPort对象的属性、事件、方法要少一些。(图片不能显示,所以不就贴图了,只是说明下情况),甚至Unity3D的有些属性还是错误的,比如BytesToRead和BytesToWrite两个属性都是“未将对象引用值对象的实例”,但是在.NET中这两个参数默认是为0。这两个参数用于接收串口发送字节数组时,是很有用处的。

unity串口控制界面(Unity3D内部串口通信与Winform的实现和异常问题)(4)

这是WinForm中串口对象里的属性

unity串口控制界面(Unity3D内部串口通信与Winform的实现和异常问题)(5)

4、虚拟串口的创建,不像是真实串口线那样子,它是以对来创建的,比如COM100与COM101一对……至于怎么成对完全是有那个创建虚拟串口的软件以及你输入的串口来决定的。

unity串口控制界面(Unity3D内部串口通信与Winform的实现和异常问题)(6)

二、Unity3D内部通信1、内部通信思路

1.1 打开串口

之前在前言中说过,Unity打开串口方式不一样,因为在.NET2.0打开串口时,如果串口超过10,则必须在前面加上“\\?\”,比如我需要打开COM301,在Unity中你实际传给串口的参数必须是“”\\?\” “COM301””。

在命名空间中引用System.IO.Ports

创建两个串口类对象

unity串口控制界面(Unity3D内部串口通信与Winform的实现和异常问题)(7)

1.2 线程接收数据

两个串口接收数据,并且打印出来,一般接收数据的方法常用的有两种,一种是接收字符串ReadLine()另一种接收字节Read,稍微我会将接收字节已注释的形式写出来。

unity串口控制界面(Unity3D内部串口通信与Winform的实现和异常问题)(8)

网关接收数据方法

unity串口控制界面(Unity3D内部串口通信与Winform的实现和异常问题)(9)

协调器接收数据方法

unity串口控制界面(Unity3D内部串口通信与Winform的实现和异常问题)(10)

1.3 发送数据

将这下面两个方法分别加入到UI Button的事件中,具体如何加这里就不解释了。

unity串口控制界面(Unity3D内部串口通信与Winform的实现和异常问题)(11)

2、代码

主要类PortsTest.cs,字节字符串转化类ClassConvert.cs。

unity串口控制界面(Unity3D内部串口通信与Winform的实现和异常问题)(12)

unity串口控制界面(Unity3D内部串口通信与Winform的实现和异常问题)(13)

unity串口控制界面(Unity3D内部串口通信与Winform的实现和异常问题)(14)

unity串口控制界面(Unity3D内部串口通信与Winform的实现和异常问题)(15)

unity串口控制界面(Unity3D内部串口通信与Winform的实现和异常问题)(16)

3、运行结果和异常解析

运行程序后,会提示网关串口打开成功和协调器串口打开成功。

3.1、当以字符串形式发送串口数据和接收串口数据时,会发现一个问题就是在接收串口数据时,会出现数据丢失的情况,网关串口向协调器发送”FF0000”时,协调器接收数据偶尔会接收到“F0000”甚至是为空,只有当连续发送两次时,才会成功。

unity串口控制界面(Unity3D内部串口通信与Winform的实现和异常问题)(17)

3.2、当以字节发送和接收串口数据时,会出现一条完整的数据会以两次打印出来。比如将“new byte[] { 0xFF, 0x00, 0x01 }”发送过去,然后打印出来的结果是第一条是FF 第二条是00 01等等情况,感觉像是随机的。

unity串口控制界面(Unity3D内部串口通信与Winform的实现和异常问题)(18)

4、当以字节发送,字符串形式接收时,是无法接收数据的

以上问题目前我也不知道是什么情况,解决思路是怎样的,发生该问题的原因可能是因为Unity对串口这块本身支持就不是很大,毕竟不是专门针对Windows平台的。

三、Unity3D与Winform程序之间的串口通信

在第一部分中介绍了Unity3D内部间的通信,现在测试Unity3D与Winform程序之间的串口通信。

首先Unity3D串口程序跟第一节类似的,只不过把网关打开串口那一部分代码移植到Winform中,然后修改一下打开串口的方式即可。

1、打开串口方式

unity串口控制界面(Unity3D内部串口通信与Winform的实现和异常问题)(19)

以上就是核心代码。

2、打开串口方式

发送字符串和接收字符串遇到以下发生过的问题

2.1 winform程序发送数据成功了,但是Unity接收不到

2.2 Unity往Winform程序总发送数据时,是没有问题的。而Unity却接收不到。

unity串口控制界面(Unity3D内部串口通信与Winform的实现和异常问题)(20)

发送字节和接收字节遇到以下发生过的问题

2.3 WinForm程序发送数据成功了,但是Unity接收到的数据存在问题,数据不符或数据中断,要想解决这个问题有两种方法:

第一可能是Unity官方的错误,如果能做成跟.NET串口通信一致的话,那么这个问题很好解决。不过这个问题不够现实,因为Unity本身就是为游戏而开发的。

第二那就自己去解决了,看到Unity接收到的数据存在数据不符,还有数据断层,只能根据自身的要求,然后去测试,添加校验位,根据首校验位和末校验位来截取你想要的字节。只有这样子你才可能接收到正常的串口数据。但是这样子也存在很多的局限性!!!

2.4 Unity往WinForm程序中发送的数据时,是没有问题的。

unity串口控制界面(Unity3D内部串口通信与Winform的实现和异常问题)(21)

unity串口控制界面(Unity3D内部串口通信与Winform的实现和异常问题)(22)

有问题可关注我的公众号(Hua灬清),我会每周推送一篇原创技术博客。

,