[英]C# SerialPort EventHandler in Unity
我正在為Unity編寫C#代碼。 只是在EventHandler中讀取SerialPort值。 問題是未調用處理程序。 這是代碼
using UnityEngine;
using System.Collections;
using System;
using System.IO.Ports;
public class MainScript : MonoBehaviour {
public SerialPort mySerialPort;
public static float speed=100;
GameObject cube ;
public GUIStyle style ;
// Use this for initialization
void Start () {
cube = GameObject.FindGameObjectWithTag ("cube");
if(mySerialPort.IsOpen)
mySerialPort.Close();
mySerialPort = new SerialPort("com5");
mySerialPort.BaudRate = 9600;
mySerialPort.Parity = Parity.None;
mySerialPort.StopBits = StopBits.None;
mySerialPort.DataBits = 8;
mySerialPort.Handshake = Handshake.None;
mySerialPort.DataReceived += new SerialDataReceivedEventHandler (DataReceivedHandler);
if(mySerialPort.IsOpen == false)
mySerialPort.Open();
}
void OnGUI(){
GUI.Box (new Rect(100,100,100,100),"Speed : " + speed , style);
}
// Update is called once per frame
void Update () {
// speed = mySerialPort.ReadTo ("\r");
// update My View with the speed new value
cube.transform.Rotate(Vector3.up * speed *Time.deltaTime);
}
public static void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
SerialPort sp = (SerialPort)sender;
speed = float.Parse( sp.ReadTo ("\r") ) ;
print ("Data Recieved : " + speed);
}
}
問題不在於串行端口,因為當我在統一更新功能中讀取它時,它會讀取正確的值,但是更新UI時存在性能問題。
謝謝
正如您所說,不會調用“ DataReceived”事件的處理程序,這是Unity的已知問題(截至今天)。 我的解決方法是使用單獨的線程讀取端口(輪詢):
private bool _looping;
private SerialPort _port;
public string _comPort; // e.g. "COM3"
private const int _baudRate = 921600;
private Thread portReadingThread;
private string strData;
private void OnEnable()
{
_looping = true;
portReadingThread = new Thread(ReadArduino);
portReadingThread.Start();
}
private void OnDestroy()
{
_looping = false; // This is a necessary command to stop the thread.
// if you comment this line, Unity gets frozen when you stop the game in the editor.
portReadingThread.Join();
portReadingThread.Abort();
_port.Close();
}
void ReadArduino()
{
// For any COM number larger than 9, you should add prefix of \\\\.\\ to it.
// For example for COM15, you should write it as "\\\\.\\COM15" instead of "COM15".
_port = new SerialPort(_comPort, _baudRate);
if (_port == null)
{
Debug.LogError("_port is null");
return;
}
_port.Handshake = Handshake.None;
_port.DtrEnable = true;
//myPort.RtsEnable = true;
_port.ReadTimeout = 500; // NOTE: Don't Reduce it or the communication might break!
_port.WriteTimeout = 1000;
_port.Parity = Parity.None;
_port.StopBits = StopBits.One;
_port.DataBits = 8;
_port.NewLine = "\n";
_port.Open();
if (!_port.IsOpen)
print("PORT HAS NOT BEEN OPEN!");
// Send "START" command to the arduino.
_port.WriteLine("START");
// Start reading the data coming through the serial port.
while (_looping)
{
strData = _port.ReadLine(); // blocking call.
print(strData);
Thread.Sleep(0);
}
}
閱讀發生在以下行中:
strData = _port.ReadLine(); // blocking call.
但它不會阻止或凍結統一性,因為它發生在單獨的線程中。
順便說一句,如果您想向端口寫入內容,只需編寫:
public void WriteToArduino()
{
_port.WriteLine("YourMessageHere");
}
您可以在游戲中的任何地方調用WriteToArduino()。 它不需要在任何特殊線程中。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.