質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
COM

COM(Component Object Model)はMicrosoftによるコンポーネントテクノロジーであり、 ソフトウェアの再利用を目的とした技術を指します。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity3D

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

シリアルポート

シリアルポートは一度に一ビットごと移行される物理的なインターフェイスです。一般的には、9ピンのd-subコネクタであるRS-232を指します。

Q&A

解決済

1回答

783閲覧

Unityでシリアル通信を行いたいが、ビルドして実行した際にSerialPortが開けない

murorin

総合スコア1

COM

COM(Component Object Model)はMicrosoftによるコンポーネントテクノロジーであり、 ソフトウェアの再利用を目的とした技術を指します。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity3D

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

シリアルポート

シリアルポートは一度に一ビットごと移行される物理的なインターフェイスです。一般的には、9ピンのd-subコネクタであるRS-232を指します。

0グッド

0クリップ

投稿2023/10/12 23:50

編集2023/10/13 05:30

実現したいこと

ビルドしたUnityの実行ファイル上で、SerialPortを開いて、シリアル通信ができるようにする

前提

Unityで自作コントローラを使った音楽ゲームを制作している者です。
コントローラ側はRaspberry Pi picoを使ったもので、シリアル通信を用いて入力用デバイスにしようとしています。

下記のコードで、Unityのエディタ上では、上手くシリアル通信が出来ており、全く問題ないのですが、ビルドしてゲームの実行ファイルからシリアル通信しようとすると、反応がなくなります。

Debug.Log()などで詳しく調べたところ、どうやら51行目の「serialPort_ = new SerialPort();」のところで問題が発生している模様です。Unityのエディタ上では全く問題のない点でしたが、ビルドすると別の問題で通信ができないのでしょうか?

以下詳細
・Windows11(メモリ:16G CPU:11th Corei7)
・Unity2022.3.10f1
・RaspberryPiPico(UARTを使用した通信)

発生している問題・エラーメッセージ

ビルドしたファイル上で、このように表示されました。(スクリプト60行目)

System.IO.Ports.SerialPort::.ctor

該当のソースコード

C#

1using UnityEngine; 2using UnityEngine.UI; 3using TMPro; 4using System.IO.Ports; 5using System.Threading; 6using System; 7 8public class Lab : MonoBehaviour 9{ 10 public TextMeshProUGUI TMP; 11 public string portName = "COM3"; 12 public int baudRate = 115200; 13 14 private SerialPort serialPort_; 15 private Thread thread_; 16 private bool isRunning_ = false; 17 private string lastrcvd = ""; 18 byte rcv; 19 char tmp; 20 21 private string message_; 22 private bool isNewMessageReceived_ = false; 23 24 void Start() 25 { 26 lastrcvd = ""; 27 Open(); 28 } 29 30 void Update() 31 { 32 if (isNewMessageReceived_) 33 { 34 //OnDataReceived(message_); 35 TMP.text = tmp.ToString(); 36 } 37 } 38 39 void OnDestroy() 40 { 41 Close(); 42 } 43 44 private void Open() 45 { 46 TMP.text = portName + "," + baudRate; 47 //serialPort_ = new SerialPort(portName, baudRate, Parity.None, 8, StopBits.One); 48 49 try 50 { 51 serialPort_ = new SerialPort(); 52 serialPort_.PortName = portName; 53 serialPort_.BaudRate = baudRate; 54 serialPort_.Parity = Parity.None; 55 serialPort_.DataBits = 8; 56 serialPort_.StopBits = StopBits.One; 57 } 58 catch (System.Exception e) 59 { 60 TMP.text = e.Message; 61 } 62 63 try 64 { 65 serialPort_.Open(); 66 serialPort_.ReadTimeout = 5000; 67 TMP.text = "[2]"; 68 } 69 catch (Exception e) 70 { 71 serialPort_ = null; 72 return; 73 } 74 75 TMP.text = "[3]"; 76 77 isRunning_ = true; 78 79 thread_ = new Thread(Read); 80 thread_.Start(); 81 } 82 83 private void Read() 84 { 85 while (isRunning_ && serialPort_ != null && serialPort_.IsOpen) 86 { 87 try 88 { 89 rcv = (byte)serialPort_.ReadByte(); 90 91 if (rcv == '\r') 92 { 93 message_ = lastrcvd; 94 //Debug.LogFormat("textLine:{0}", message_); 95 lastrcvd = ""; 96 isNewMessageReceived_ = true; 97 } 98 else 99 { 100 tmp = (char)rcv; 101 //Debug.LogFormat("rcv:{0}", tmp.ToString()); 102 lastrcvd = lastrcvd + tmp.ToString(); 103 } 104 } 105 catch (System.Exception e) 106 { 107 Debug.LogWarning(e.Message); 108 } 109 } 110 } 111 112//追記 113void OnDestroy() 114 { 115 Debug.Log("close"); 116 Close(); 117 } 118 119private void Close() 120 { 121 isRunning_ = false; 122 123 if (thread_ != null && thread_.IsAlive) 124 { 125 thread_.Join(); 126 } 127 128 if (serialPort_ != null && serialPort_.IsOpen) 129 { 130 Debug.Log("close2"); 131 serialPort_.Close(); 132 serialPort_.Dispose(); 133 } 134 } 135 136 137

試したこと

・PlayerSettingsで「Api Compatibility Level」 ⇒ 「.NET Flamework」

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

エディタ上では全く問題のない点

で、そいつがシリアルポートを握ったままなのでビルド~実行したヒトが接続できない、とかいうのはありがちですがそういうことではないですか? シリアルポートは一つの接続が独占、排他的に使用されます。誰かが使用中だと他のヒトは使用できません。

あとは、デバイスを繋ぎ変えたらCOMポート番号が変わっちゃってたり、とか。Raspberry Pi Picoは挿し替えてもポート番号変わらなかった気がするけれど、一般論としてチェックすべき項目ではあるでしょう。

投稿2023/10/13 03:33

thkana

総合スコア7639

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

murorin

2023/10/13 05:14

返信ありがとうございます! 一つのシリアルポートの通信がが独占すること、排他的であることを初めて知りました。勉強になります。 >>シリアルポートを握ったままなのでビルド~実行したヒトが接続できない  本文には掲載していませんでしたが、Unityエディタ上で、実行を終了した後、以下のClose関数が実行されるようになっています。  Debug.Log()を使って調べた感じでも、しっかり実行されていました。「serialPort_.Close();」「serialPort_.Dispose();」だけでは、シリアルポートの解放が出来ていないのでしょうか? 間違っているのであれば、よろしければシリアルポートの開放の仕方を教えていただきたいです。  また、COMポート番号は変わらずでした。  無知ですみません。何卒よろしくお願いいたします。 ### ソースコード void OnDestroy() { Debug.Log("close"); Close(); } private void Close() { isRunning_ = false; if (thread_ != null && thread_.IsAlive) { thread_.Join(); } if (serialPort_ != null && serialPort_.IsOpen) { Debug.Log("close2"); serialPort_.Close(); serialPort_.Dispose(); } }
thkana

2023/10/13 06:35

> シリアルポートの開放の仕方 (開放->解放) 現時点では、ポートを握っているプログラム(プロセス)を終了してしまえば用は足りるでしょう。 COMポートを誰かに握られているかどうかのチェックとしては PicoをArduino IDEで使っているならArduino IDEのシリアルモニタでCOM3を開いてみるとか、 PCにPythonをインストールしてあるならIDLEかなにかでCOM3を開いてみるとか、 あるいはTeraTermなどのシリアル対応のターミナルプログラムを入れてCOM3を開いてみるとか、 いろいろ試す方法はあると思います。そういうので開けるならまた別の問題ですね。
murorin

2023/10/14 06:43

返信ありがとうございます! IL2CPP→monoに戻したらビルドしても通信できるようになっていました。(理屈はよくわかりませんが…) ポート関係は特に問題なかったようです。 色々勉強になりました! お付き合いいただきありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問