注:以下文章是我收錄兩年前記錄的CSDN博客。
一、前言
1、有些人其實(shí)會(huì)覺得Unity3D用到的.NET是2.0的,其實(shí)不然;Unity3D有用到.NET3.5,為什么說Unity用到的是3.5呢,從一個(gè)很常用卻很重要的一個(gè)命名空間說起,他就是System.Linq命名空間,這個(gè)命名空間是.NET3.5重要的一次改革和核心部分(本命名空間與該文章并沒有什么很大的聯(lián)系,只是提下而已)。至于為什么顯示成2.0我也不是很清楚,可能只支持部分3.5吧,不過對我們來說關(guān)系并不是很大。只要支持Linq就可以了。
2、前提工作:虛擬串口和Unity3D切換成.NET。
????2.1 虛擬串口的創(chuàng)建,可以從網(wǎng)上下載一個(gè)創(chuàng)建虛擬串口的軟件,比如“VSPD虛擬串口”,還是挺好用的,不過因?yàn)槲易鯱nity3D的虛擬串口工作,所以根據(jù)VSPD專門寫了一個(gè)創(chuàng)建虛擬串口的程序(暫時(shí)不提供)。在創(chuàng)建虛擬串口的時(shí)候注意一個(gè)很重要的問題,就是盡量創(chuàng)建串口號大于10的,比如COM10、COM11甚至夸張點(diǎn)COM100等,為什么要這樣子,后面我會(huì)介紹Unity3D打開串口時(shí),串口號大于10時(shí),打開串口方式與.NET打開串口的方式是不一樣的。
????2.2 將Unity3D的API平臺切換成.NET2.0。如何切換“Edit–project Setting–Player–Other Setting –Api Compatibility level”。在這里將“.NET2.0 Subset”切換為“.NET2.0”。
????2.3 Unity的目標(biāo)平臺一定要切換為Windows平臺,否則是其他平臺會(huì)報(bào)錯(cuò)誤,本人就是深有體會(huì),針對這個(gè)問題找原因找了很久,什么百度、谷歌、論壇都查閱了,最后還是無意中自己發(fā)現(xiàn)解決的了。
切換為Web平臺時(shí)報(bào)的錯(cuò)誤
3、Unity的串口與.NET的串口對象參數(shù)有些不一樣,比如在Unity3D中打開串口,SerialPort對象的屬性、方法、事件等要比.NET SerialPort對象的屬性、事件、方法要少一些。(圖片不能顯示,所以不就貼圖了,只是說明下情況),甚至Unity3D的有些屬性還是錯(cuò)誤的,比如BytesToRead和BytesToWrite兩個(gè)屬性都是“未將對象引用值對象的實(shí)例”,但是在.NET中這兩個(gè)參數(shù)默認(rèn)是為0。這兩個(gè)參數(shù)用于接收串口發(fā)送字節(jié)數(shù)組時(shí),是很有用處的。
這是WinForm中串口對象里的屬性
4、虛擬串口的創(chuàng)建,不像是真實(shí)串口線那樣子,它是以對來創(chuàng)建的,比如COM100與COM101一對……至于怎么成對完全是有那個(gè)創(chuàng)建虛擬串口的軟件以及你輸入的串口來決定的。
二、Unity3D內(nèi)部通信
1、內(nèi)部通信思路
1.1 打開串口
????之前在前言中說過,Unity打開串口方式不一樣,因?yàn)樵?NET2.0打開串口時(shí),如果串口超過10,則必須在前面加上“\\?\”,比如我需要打開COM301,在Unity中你實(shí)際傳給串口的參數(shù)必須是“”\\?\” + “COM301””。
????在命名空間中引用System.IO.Ports
????創(chuàng)建兩個(gè)串口類對象
1.2 線程接收數(shù)據(jù)
????兩個(gè)串口接收數(shù)據(jù),并且打印出來,一般接收數(shù)據(jù)的方法常用的有兩種,一種是接收字符串ReadLine()另一種接收字節(jié)Read,稍微我會(huì)將接收字節(jié)已注釋的形式寫出來。
????網(wǎng)關(guān)接收數(shù)據(jù)方法
????協(xié)調(diào)器接收數(shù)據(jù)方法
????1.3 發(fā)送數(shù)據(jù)
????將這下面兩個(gè)方法分別加入到UI Button的事件中,具體如何加這里就不解釋了。
2、代碼
????主要類PortsTest.cs,字節(jié)字符串轉(zhuǎn)化類ClassConvert.cs。
3、運(yùn)行結(jié)果和異常解析
運(yùn)行程序后,會(huì)提示網(wǎng)關(guān)串口打開成功和協(xié)調(diào)器串口打開成功。
????3.1、當(dāng)以字符串形式發(fā)送串口數(shù)據(jù)和接收串口數(shù)據(jù)時(shí),會(huì)發(fā)現(xiàn)一個(gè)問題就是在接收串口數(shù)據(jù)時(shí),會(huì)出現(xiàn)數(shù)據(jù)丟失的情況,網(wǎng)關(guān)串口向協(xié)調(diào)器發(fā)送”FF0000”時(shí),協(xié)調(diào)器接收數(shù)據(jù)偶爾會(huì)接收到“F0000”甚至是為空,只有當(dāng)連續(xù)發(fā)送兩次時(shí),才會(huì)成功。
????3.2、當(dāng)以字節(jié)發(fā)送和接收串口數(shù)據(jù)時(shí),會(huì)出現(xiàn)一條完整的數(shù)據(jù)會(huì)以兩次打印出來。比如將“new byte[] { 0xFF, 0x00, 0x01 }”發(fā)送過去,然后打印出來的結(jié)果是第一條是FF 第二條是00 01等等情況,感覺像是隨機(jī)的。
4、當(dāng)以字節(jié)發(fā)送,字符串形式接收時(shí),是無法接收數(shù)據(jù)的
以上問題目前我也不知道是什么情況,解決思路是怎樣的,發(fā)生該問題的原因可能是因?yàn)閁nity對串口這塊本身支持就不是很大,畢竟不是專門針對Windows平臺的。
三、Unity3D與Winform程序之間的串口通信
????在第一部分中介紹了Unity3D內(nèi)部間的通信,現(xiàn)在測試Unity3D與Winform程序之間的串口通信。
????首先Unity3D串口程序跟第一節(jié)類似的,只不過把網(wǎng)關(guān)打開串口那一部分代碼移植到Winform中,然后修改一下打開串口的方式即可。
1、打開串口方式
以上就是核心代碼。
2、打開串口方式
發(fā)送字符串和接收字符串遇到以下發(fā)生過的問題
????2.1 winform程序發(fā)送數(shù)據(jù)成功了,但是Unity接收不到
????2.2 Unity往Winform程序總發(fā)送數(shù)據(jù)時(shí),是沒有問題的。而Unity卻接收不到。
發(fā)送字節(jié)和接收字節(jié)遇到以下發(fā)生過的問題
????2.3 WinForm程序發(fā)送數(shù)據(jù)成功了,但是Unity接收到的數(shù)據(jù)存在問題,數(shù)據(jù)不符或數(shù)據(jù)中斷,要想解決這個(gè)問題有兩種方法:
第一可能是Unity官方的錯(cuò)誤,如果能做成跟.NET串口通信一致的話,那么這個(gè)問題很好解決。不過這個(gè)問題不夠現(xiàn)實(shí),因?yàn)閁nity本身就是為游戲而開發(fā)的。
第二那就自己去解決了,看到Unity接收到的數(shù)據(jù)存在數(shù)據(jù)不符,還有數(shù)據(jù)斷層,只能根據(jù)自身的要求,然后去測試,添加校驗(yàn)位,根據(jù)首校驗(yàn)位和末校驗(yàn)位來截取你想要的字節(jié)。只有這樣子你才可能接收到正常的串口數(shù)據(jù)。但是這樣子也存在很多的局限性!!!
????2.4 Unity往WinForm程序中發(fā)送的數(shù)據(jù)時(shí),是沒有問題的。