最近需要在Unity中实现自动识别热拔插并识别串口的功能,实在没有找到原生的消息响应,折腾了一周,尝试了多种方法,总结一下主要有3种实现思路。
1.利用Form类中的消息进行串口拔插消息的接收。
2.实时保存串口信息到外部文件,进行判别。
3.读取注册表中的信息进行判别。
首先说一下在Unity中对串口的支持并不是很好,串口识别部分见下面的连接,这里主要讲述如何获取串口拔插的消息,并进行响应。https://blog.csdn.net/zhoudapeng01/article/details/90296515
方法一,利用Form类中的消息进行串口拔插消息的接收,借鉴了文章http://www.cnblogs.com/virusswb/archive/2008/08/22/1274085.html
最终失败。主要原因是因为Unity执行结束后会导致崩溃,APPCrash。添加了一个空物体,挂载消息控制,代码如下。
https://download.csdn.net/download/zhoudapeng01/11185452
方法二,实时保存串口信息到外部文件,进行判别。主要思路是利用一个外部的exe每隔一个小的时间间隔,保存串口信息到外部文件,Unity3d中每次刷新的时候读取文件,通过比较串口的变化,进行判别,这里使用json作为文件格式。
保存json的代码:https://download.csdn.net/download/zhoudapeng01/11185507
Unity中调用外部exe:
try
{
//Process.Start("GetPortName.exe");
myprocess = new Process();
ProcessStartInfo startInfo = new ProcessStartInfo("F:GetPortState.exe");
myprocess.StartInfo = startInfo;
myprocess.StartInfo.WorkingDirectory = "F:\\ZZB-Unity\\GetPortName\\GetPortName\\GetPortName\\bin\\Release\\GetPortState";
myprocess.StartInfo.UseShellExecute = false;
myprocess.StartInfo.RedirectStandardOutput = true;
myprocess.Start();
}
catch (Exception ex)
{
UnityEngine.Debug.Log("出错原因:" + ex.Message);
}
方法三,读取注册表中的信息进行判别,使用过程中存在一些问题,有些时候串口已经拔出但是注册表中的信息并没有改变。虽然存在一些问题,综合考虑使用了这种方法。保存注册表中的信息到list中,在刷新的时候检查list是否有变动(可以检查元素个数)通过这种方式判断拔插,结合上一篇博客中根据串口名称读取串口号,就可以实时打开和关闭串口。
private void GetPortFromReg(List<string> portReg)
{
portReg.Clear();
RegistryKey keyCom = Registry.LocalMachine.OpenSubKey("Hardware\\DeviceMap\\SerialComm");
if (keyCom != null)
{
string[] sSubKeys = keyCom.GetValueNames();
foreach (string sName in sSubKeys)
{
string sValue = (string)keyCom.GetValue(sName);
portReg.Add(sValue);
}
}
}