Unity调用派样机流程

本文详细介绍了如何使用Unity开发一个结合微信二维码扫描的互动程序,当用户完成互动后,通过服务器指令控制派样机送出小礼物。开发过程中涉及的主要难点包括接收服务器信号并触发派样,以及通过串口通信调用派样机硬件。通过Unity创建UI、实现网络请求及串口通信功能,成功实现了派样机的自动化操作。

一、需求梳理

当时公司让实现一个什么样的功能呐?就是在派样机(类似于饮料自动购物机那种机器)上的电脑上,开发一款Unity程序,这款程序上有一个二维码,用户用微信扫一扫扫这个二维码,这时用户的手机上就会出现一个互动的小程序,用户互动完成后,服务器判断用户互动完成,给派样机的Unity程序发一个网络指令。Unity程序收到该指令后,使用串口通信给派样机发一个指令,派样机硬件收到该指令后,即调用硬件推出一个小礼物,送给用户。
这个项目不是什么很复杂的项目,这里面有两个难点。1.获取服务器传过来的信号,进行判断。2.判断完毕服务器的信号后,调用派样机,调用硬件进行派样。只要开发完成这两个功能后,这个项目就算是完成了。

二、开发步骤

1.首先在Unity中创建UI,将二维码贴在Unity的程序里的UI上,UI如下图所示。
2.开发获取服务器指令功能,并且进行判断,如果获取到正确的信息,即对派样机发送派样指令,代码如下。
    
using System ; using System . Collections ; using System . Collections . Generic ; using UnityEngine ; using UnityEngine . Networking ; using Newtonsoft . Json ; using UnityEngine . UI ; public class HttpNet : MonoBehaviour { Action callback ; /// <summary> /// 派样机字符类 /// </summary> public ComManager comManager ; // Start is called before the first frame update void Start ( ) { callback += Dispchater ; StartCoroutine ( GetData ( callback ) ) ; } private void Dispchater ( ) { //Debug.Log("掉小样!"); comManager . DemoMechineSendCom ( ) ; } //加载路径图片 IEnumerator GetData ( Action action ) //Action action { while ( true ) { yield return new WaitForSeconds ( 2.0f ) ; UnityWebRequest unityWebRequest = UnityWebRequest . Get ( "https://www.brandxspace.com/development/sendPrototype/getPrototypeState?flag=0" ) ; //UnityWebRequest unityWebRequest = UnityWebRequest.Get(jsonUrl); yield return unityWebRequest . SendWebRequest ( ) ; if ( ! unityWebRequest . isNetworkError ) { string data = unityWebRequest . downloadHandler . text ; Data d = JsonConvert . DeserializeObject < Data > ( data ) ; if ( d != null ) { Debug . Log ( data + "------" ) ; if ( d . status == "1" ) { //掉小样 if ( action != null ) { action ( ) ; } } } } } } } public class Data { public string status ; public String message ; public object data ; }
3.开发调用派样机派样功能,该功能主要使用的是串口通信开发,如果对串口通信开发很熟悉的话这个也是十分简单的功能,主要是通过代码设置派样的顺序和速率,代码如下: (1)CRC.CS
    
using System ; using System . Collections . Generic ; using System . Linq ; using System . Text ; public class CRC { # region CRC16 public static byte [ ] CRC16 ( byte [ ] data ) { int len = data . Length ; if ( len > 0 ) { ushort crc = 0xFFFF ; for ( int i = 0 ; i < len ; i ++ ) { crc = ( ushort ) ( crc ^ ( data [ i ] ) ) ; for ( int j = 0 ; j < 8 ; j ++ ) { crc = ( crc & 1 ) != 0 ? ( ushort ) ( ( crc >> 1 ) ^ 0xA001 ) : ( ushort ) ( crc >> 1 ) ; } } byte hi = ( byte ) ( ( crc & 0xFF00 ) >> 8 ) ; //高位置 byte lo = ( byte ) ( crc & 0x00FF ) ; //低位置 return new byte [ ] { hi , lo } ; } return new byte [ ] { 0 , 0 } ; } # endregion # region ToCRC16 public static string ToCRC16 ( string content ) { return ToCRC16 ( content , Encoding . UTF8 ) ; } public static string ToCRC16 ( string content , bool isReverse ) { return ToCRC16 ( content , Encoding . UTF8 , isReverse ) ; } public static string ToCRC16 ( string content , Encoding encoding ) { return ByteToString ( CRC16 ( encoding . GetBytes ( content ) ) , true ) ; } public static string ToCRC16 ( string content , Encoding encoding , bool isReverse ) { return ByteToString ( CRC16 ( encoding . GetBytes ( content ) ) , isReverse ) ; } public static string ToCRC16 ( byte [ ] data ) { return ByteToString ( CRC16 ( data ) , true ) ; } public static string ToCRC16 ( byte [ ] data , bool isReverse ) { return ByteToString ( CRC16 ( data ) , isReverse ) ; } # endregion # region ToModbusCRC16 public static string ToModbusCRC16 ( string s ) { return ToModbusCRC16 ( s , true ) ; } public static string ToModbusCRC16 ( string s , bool isReverse ) { return ByteToString ( CRC16 ( StringToHexByte ( s ) ) , isReverse ) ; } public static string ToModbusCRC16 ( byte [ ] data ) { return ToModbusCRC16 ( data , true ) ; } public static string ToModbusCRC16 ( byte [ ] data , bool isReverse ) { return ByteToString ( CRC16 ( data ) , isReverse ) ; } # endregion # region ByteToString public static string ByteToString ( byte [ ] arr , bool isReverse ) { try { byte hi = arr [ 0 ] , lo = arr [ 1 ] ; return Convert . ToString ( isReverse ? hi + lo * 0x100 : hi * 0x100 + lo , 16 ) . ToUpper ( ) . PadLeft ( 4 , '0' ) ; } catch ( Exception ex ) { throw ( ex ) ; } } public static string ByteToString ( byte [ ] arr ) { try { return ByteToString ( arr , true ) ; } catch ( Exception ex ) { throw ( ex ) ; } } # endregion # region StringToHexString public static string StringToHexString ( string str ) { StringBuilder s = new StringBuilder ( ) ; foreach ( short c in str . ToCharArray ( ) ) { s . Append ( c . ToString ( "X4" ) ) ; } return s . ToString ( ) ; } # endregion # region StringToHexByte private static string ConvertChinese ( string str ) { StringBuilder s = new StringBuilder ( ) ; foreach ( short c in str . ToCharArray ( ) ) { if ( c <= 0 || c >= 127 ) { s . Append ( c . ToString ( "X4" ) ) ; } else { s . Append ( ( char ) c ) ; } } return s . ToString ( ) ; } private static string FilterChinese ( string str ) { StringBuilder s = new StringBuilder ( ) ; foreach ( short c in str . ToCharArray ( ) ) { if ( c > 0 && c < 127 ) { s . Append ( ( char ) c ) ; } } return s . ToString ( ) ; } /// <summary> /// 字符串转16进制字符数组 /// </summary> /// <param name="hex"></param> /// <returns></returns> public static byte [ ] StringToHexByte ( string str ) { return StringToHexByte ( str , false ) ; } /// <summary> /// 字符串转16进制字符数组 /// </summary> /// <param name="str"></param> /// <param name="isFilterChinese">是否过滤掉中文字符</param> /// <returns></returns> public static byte [ ] StringToHexByte ( string str , bool isFilterChinese ) { string hex = isFilterChinese ? FilterChinese ( str ) : ConvertChinese ( str ) ; //清除所有空格 hex = hex . Replace ( " " , "" ) ; //若字符个数为奇数,补一个0 hex += hex . Length % 2 != 0 ? "0" : "" ; byte [ ] result = new byte [ hex . Length / 2 ] ; for ( int i = 0 , c = result . Length ; i < c ; i ++ ) { result [ i ] = Convert . ToByte ( hex . Substring ( i * 2 , 2 ) , 16 ) ; } return result ; } # endregion }
(2)ComManager.cs
    
using UnityEngine ; using System . Collections ; using System ; using System . Threading ; using System . Collections . Generic ; using System . IO . Ports ; public class ComManager : MonoBehaviour { //public ComManager instance; //端口号 string com2 = "" ; private SerialPort sp2 ; //波特率 private int baudRate ; public float timer = 0.1f ; //private bool isShinning = false; //配置文件管理类 public ConfigTest configTest ; //private void Awake() //{ //instance = this; //} void Start ( ) { //string com2 = "COM7"; com2 = configTest . dic [ "端口号" ] [ "portName" ] ; baudRate = int . Parse ( configTest . dic [ "波特率" ] [ "baudRate" ] ) ; //row = 8; row = int . Parse ( configTest . dic [ "参数" ] [ "row" ] ) ; //column = 4; column = int . Parse ( configTest . dic [ "参数" ] [ "column" ] ) ; //depth = 5; depth = int . Parse ( configTest . dic [ "参数" ] [ "depth" ] ) ; mainCount = int . Parse ( configTest . dic [ "参数" ] [ "mainCount" ] ) ; StartCoroutine ( StartCom ( ) ) ; } IEnumerator StartCom ( ) { yield return new WaitForSeconds ( 0.1f ) ; sp2 = new SerialPort ( com2 , baudRate , Parity . None , 8 , StopBits . One ) ; if ( ! sp2 . IsOpen ) { sp2 . Open ( ) ; } } /// <summary> /// 派样机串口 /// </summary> /// <param name="data"></param> private void SendDemoMechineData ( byte [ ] data ) { if ( sp2 . IsOpen ) { sp2 . Write ( data , 0 , data . Length ) ; } } void OnDisable ( ) { if ( sp2 . IsOpen ) { sp2 . Close ( ) ; } } private int row ; //8 private int column ; //5 private int depth ; //10 private int mainCount = 40 ; //总数 private static int index = 0 ; public void DemoMechineSendCom ( ) { int tempRow = index % row ; //第几个 int tempColumn = ( index / row ) % row ; //第几行 int tempdepth = index / ( row * column ) % depth ; Debug . Log ( index + " row: " + tempRow + "col: " + tempColumn + "depth " + tempdepth ) ; string pos = tempColumn . ToString ( "0" ) + tempRow . ToString ( "0" ) ; string corPos = System . Convert . ToString ( int . Parse ( pos ) , 16 ) . PadLeft ( 2 , '0' ) ; string data = "0105" + corPos + "030000000000000000000000000000" ; byte [ ] byteData = CRC . StringToHexByte ( data ) ; byte [ ] crcByteData = CRC . CRC16 ( byteData ) ; //Debug.Log(CRC.ByteToString(crcByteData)); data += CRC . ByteToString ( crcByteData ) ; //Debug.Log(data); byte [ ] byteDatas = CRC . StringToHexByte ( data ) ; SendDemoMechineData ( byteDatas ) ; index ++ ; if ( index >= mainCount ) { index = 0 ; } } }

三、小结

就这样,派样机的功能就基本开发完成了。虽然功能十分简单,但是用处很大,创作不易,如果喜欢文章,请点个赞。另外安利一波本人新开的网店,如果有什么需求自己做的费劲,可以在网店联系我,我会尽力帮助大家,希望大家支持一下。网店地址 小程工作室
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值