This page goes over the foundational settings for serial communication between Arduino and Unity.

Arduino

void setup() {
  Serial.begin(9600); // start serial Port
}

void loop()
{
  //send string through serial
  Serial.print("Hello, this is Arduino.");
  Serial.println();
  delay(1000);
}

Unity

Project Settings:

Edit → Project Settings → Player →Other Settings → Configuration → API Compatibility Level → .NET Framework

image.png

Serial message handling scripts:

SerialHandler.cs:

using UnityEngine;
using System.Collections;
using System.IO.Ports;
using System.Threading;

public class SerialHandler : MonoBehaviour
{
    public delegate void SerialDataReceivedEventHandler(string message);
    public event SerialDataReceivedEventHandler OnDataReceived;

    //Port name examples
    //Linux: /dev/ttyUSB0
    //windows: COM1
    //Mac: /dev/tty.usbmodem1421
    public string portName = "COM3";
    public int baudRate = 9600;

    private SerialPort serialPort_;
    private Thread thread_;
    private bool isRunning_ = false;

    private string message_;
    private bool isNewMessageReceived_ = false;

    void Awake()
    {
        Open();
    }

    void Update()
    {
        if (isNewMessageReceived_)
        {
            OnDataReceived(message_);
        }
        isNewMessageReceived_ = false;
    }

    void OnDestroy()
    {
        Close();
    }

    private void Open()
    {
        serialPort_ = new SerialPort(portName, baudRate, Parity.None, 8, StopBits.One);
        //or
        //serialPort_ = new SerialPort(portName, baudRate);
        serialPort_.Open();

        isRunning_ = true;

        thread_ = new Thread(Read);
        thread_.Start();
    }

    private void Close()
    {
        isNewMessageReceived_ = false;
        isRunning_ = false;

        if (thread_ != null && thread_.IsAlive)
        {
            thread_.Join();
        }

        if (serialPort_ != null && serialPort_.IsOpen)
        {
            serialPort_.Close();
            serialPort_.Dispose();
        }
    }

    private void Read()
    {
        while (isRunning_ && serialPort_ != null && serialPort_.IsOpen)
        {
            try
            {
                message_ = serialPort_.ReadLine();
                isNewMessageReceived_ = true;
            }
            catch (System.Exception e)
            {
                Debug.LogWarning(e.Message);
            }
        }
    }

    public void Write(string message)
    {
        try
        {
            serialPort_.Write(message);
        }
        catch (System.Exception e)
        {
            Debug.LogWarning(e.Message);
        }
    }
}

SerialReceive.cs:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SerialReceive : MonoBehaviour
{
    //SerialHandler.c class
    public SerialHandler serialHandler;

    void Start()
    {
        //handle recived message
        serialHandler.OnDataReceived += OnDataReceived;
    }

    //message handler
    void OnDataReceived(string message)
    {
        var data = message.Split(
                new string[] { "\\n" }, System.StringSplitOptions.None);
        try
        {
            Debug.Log(data[0]);//display on unity console
        }
        catch (System.Exception e)
        {
            Debug.LogWarning(e.Message);//raise error exception
        }
    }
}