Skip to content

Instantly share code, notes, and snippets.

@XakazukinX
Last active November 27, 2019 20:49
Show Gist options
  • Save XakazukinX/5aaad49be4a5e293593dfa2ffb9ccbb1 to your computer and use it in GitHub Desktop.
Save XakazukinX/5aaad49be4a5e293593dfa2ffb9ccbb1 to your computer and use it in GitHub Desktop.
Unityでシリアル通信を受けるためのクラス
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO.Ports;
using System.Threading;
using System.Threading.Tasks;
using UnityEditor;
using UnityEngine;
namespace SerialPortUtility
{
public enum BaudRate
{
B_300 = 300,
B_1200 = 1200,
B_2400 = 2400,
B_4800 = 4800,
B_9600 = 9600,
B_19200 = 19200,
B_38400 = 38400,
B_57600 = 57600,
B_74880 = 74880,
B_115200 = 115200,
B_230400 = 230400,
B_250000 = 250000
}
public class SerialPortProviderBase : MonoBehaviour
{
private SynchronizationContext _mainContext;
[Serializable]
public class SerialPortSetting
{
public BaudRate baudRate = BaudRate.B_57600;
public int selectedPort;
public string targetPortName;
}
[SerializeField] private SerialPortSetting _serialPortSetting = new SerialPortSetting();
private SerialPort serialStream = new SerialPort();
private bool isSerialReadRunning;
public virtual void Start()
{
_mainContext = SynchronizationContext.Current;
serialStream = new SerialPort(_serialPortSetting.targetPortName, (int) _serialPortSetting.baudRate);
serialStream.Open();
serialStream.DiscardInBuffer();
serialStream.DiscardOutBuffer();
isSerialReadRunning = true;
//受信処理はTaskに名月破にしておく
Task.Run(ReadSerialPort);
}
private void OnDestroy()
{
CloseSerialStream();
}
public virtual void CloseSerialStream()
{
isSerialReadRunning = false;
serialStream.Close();
}
private void ReadSerialPort()
{
while (serialStream.IsOpen && serialStream != null && isSerialReadRunning)
{
if (serialStream.BytesToRead == 0) continue;
try
{
while (serialStream.BytesToRead != 0)
{
var readData = (byte) serialStream.ReadByte();
_mainContext.Post(_ => StreamReadBehavior(serialStream, readData), null);
}
}
catch (Exception e)
{
Debug.LogWarning(e.Message);
}
}
}
public virtual void StreamReadBehavior(SerialPort serialPort, byte readData)
{
}
#if UNITY_EDITOR
[CustomPropertyDrawer(typeof(SerialPortSetting))]
public class SerialPortSettingDrawer : PropertyDrawer
{
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
EditorGUI.indentLevel++;
position.height = EditorGUIUtility.singleLineHeight;
var defaultPos = position;
position.x = defaultPos.x;
position.height = EditorGUIUtility.singleLineHeight;
EditorGUI.PropertyField(position, property);
if (!property.isExpanded) return;
position.y += EditorGUIUtility.singleLineHeight;
EditorGUI.LabelField(position, "ボーレート");
position.x = defaultPos.width * 0.5f;
var baudRateProperty = property.FindPropertyRelative("baudRate");
baudRateProperty.enumValueIndex = EditorGUI.Popup(position, baudRateProperty.enumValueIndex,
Enum.GetNames(typeof(BaudRate)));
position.x = defaultPos.x;
position.y += EditorGUIUtility.singleLineHeight;
EditorGUI.LabelField(position, "シリアルポート");
position.x = defaultPos.width * 0.5f;
var selectedPortProperty = property.FindPropertyRelative("selectedPort");
var names = SerialPort.GetPortNames();
if (names.Length == 0)
{
names = new string[] {"No Serial Device"};
selectedPortProperty.intValue = 0;
selectedPortProperty.intValue =
EditorGUI.Popup(position, selectedPortProperty.intValue, names);
}
else
{
selectedPortProperty.intValue =
EditorGUI.Popup(position, selectedPortProperty.intValue, names);
}
var targetPortNameProperty = property.FindPropertyRelative("targetPortName");
targetPortNameProperty.stringValue = names[selectedPortProperty.intValue];
EditorGUI.indentLevel--;
}
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
if (!property.isExpanded) return EditorGUIUtility.singleLineHeight;
return EditorGUIUtility.singleLineHeight * 3.5f;
}
}
}
#endif
}
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO.Ports;
using System.Text;
using SerialPortUtility;
using UnityEngine;
public class SerialPortReadLineProvider : SerialPortProviderBase
{
private StringBuilder builder = new StringBuilder();
public static Action<string> OnGetReadLine;
public override void StreamReadBehavior(SerialPort serialPort, byte readData)
{
char readChar = (char) readData;
if (readChar == '\n')
{
OnGetReadLine?.Invoke(builder.ToString());
Debug.Log(builder.ToString());
builder.Clear();
}
else
{
builder.Append(readChar);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment