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

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

新規登録して質問してみよう
ただいま回答率
85.35%
C#

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

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

Q&A

解決済

2回答

7239閲覧

UnityとArduinoのシリアル通信に関して

Yomihalaalpha

総合スコア4

C#

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

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

0グッド

0クリップ

投稿2020/06/24 10:31

編集2020/06/24 22:33

Serial通信を用いてArduinoとUnityを通信させたいのですがうまく動きません。

まず、SerialPortsクラスを使用するためにSystem.IO.Portsのバージョン4.7.0のdllファイルをAssetフォルダにコピーしました。そして下記のコードを記述してコンパイルしたのですが、「名前空間が重複している」という旨のエラーが出ました。
(Unityのバージョンは2019.3.13f1です。)

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

Assets\SerialHandler.cs(14,13): error CS0433: The type 'SerialPort' exists in both 'System.IO.Ports, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51' and 'System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'

該当のソースコード

c#

1using UnityEngine; 2using System.Collections; 3using System.IO.Ports; 4using System.Threading; 5 6public class SerialHandler : MonoBehaviour 7{ 8 public delegate void SerialDataReceivedEventHandler(string message); 9 public event SerialDataReceivedEventHandler OnDataReceived; 10 11 public string portName = "COM4"; 12 public int baudRate = 9600; 13 14 private SerialPort serialPort_; 15 private Thread thread_; 16 private bool isRunning_ = false; 17 18 private string message_; 19 private bool isNewMessageReceived_ = false; 20 21 void Awake() 22 { 23 Open(); 24 } 25 26 void Update() 27 { 28 if (isNewMessageReceived_) 29 { 30 OnDataReceived(message_); 31 Debug.Log(message_); 32 } 33 isNewMessageReceived_ = false; 34 } 35 36 void OnDestroy() 37 { 38 Close(); 39 } 40 41 private void Open() 42 { 43 serialPort_ = new SerialPort(portName, baudRate, Parity.None, 8, StopBits.One); 44 //または 45 //serialPort_ = new SerialPort(portName, baudRate); 46 serialPort_.Open(); 47 48 isRunning_ = true; 49 50 thread_ = new Thread(Read); 51 thread_.Start(); 52 } 53 54 private void Close() 55 { 56 isNewMessageReceived_ = false; 57 isRunning_ = false; 58 59 if (thread_ != null && thread_.IsAlive) 60 { 61 thread_.Join(); 62 } 63 64 if (serialPort_ != null && serialPort_.IsOpen) 65 { 66 serialPort_.Close(); 67 serialPort_.Dispose(); 68 } 69 } 70 71 private void Read() 72 { 73 while (isRunning_ && serialPort_ != null && serialPort_.IsOpen) 74 { 75 try 76 { 77 message_ = serialPort_.ReadLine(); 78 isNewMessageReceived_ = true; 79 } 80 catch (System.Exception e) 81 { 82 Debug.LogWarning(e.Message); 83 } 84 } 85 } 86 87 public void Write(string message) 88 { 89 try 90 { 91 serialPort_.Write(message); 92 } 93 catch (System.Exception e) 94 { 95 Debug.LogWarning(e.Message); 96 } 97 } 98} 99

試したこと

調べてみて、重複しているクラスを削除する必要があることがわかったのですが、dllファイルのため内部を閲覧できず挫折しました。他に解決する方法をご存知の方は教えていただけると大変助かります。

コンパイルオプションを変更する必要があることがわかったのですが、C#スクリプトがUnityに紐づけされているためか、設定画面を開こうとしても以下のような表示になってしまいます。
イメージ説明

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

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

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

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

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

guest

回答2

0

ベストアンサー

まず、SerialPortsクラスを使用するためにSystem.IO.Portsのバージョン4.7.0のdllファイルをAssetフォルダにコピーしました。

これが間違いの始まりです。Unity は .NET Framework 上で動いているわけではないので、.NET Framework のアセンブリ (dll) ファイルを Unity のプロジェクトの中に入れても動きません。Unity Arduino で検索すると出てくるページ()で示しているように、API Compatibility Level を Subset ではなく 2.0 とか 4.0 に設定しておけば、System.IO.Ports は多分使えるようになります(確認はしていません)。

つまり Assets にコピーした dll ファイルを削除して API Compatibility Level を適切に設定すればそのコードは動くようになるでしょう。

「多分」と言ったのは、Unity は mono という .NET 互換のランタイム上で動いていて、その互換性は完全ではないからです。つまり .NET Framework 上にある名前空間やクラスでも Unity (mono) から使えないものもたまにあります。なのでその辺は試してください。

投稿2020/07/01 17:30

編集2020/07/01 17:36
bboydaisuke

総合スコア5308

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

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

Yomihalaalpha

2020/07/02 12:50

その通りに設定したらちゃんと動きました。Arduinoの値もバッチリ取れてます。本当にありがとうございます! 助かりました。
guest

0

エラーは、SerialPort型が、System.IO.Ports.SerialPortなのか、System.SerialPortのどちらか不明だというものです。
ですので、以下のようにすれば、コンパイルができるようになるかと思います。

public class SerialHandler : MonoBehaviour {   (中略) private System.IO.Ports.SerialPort serialPort_;   (中略) private void Open() { serialPort_ = new System.IO.Ports.SerialPort(portName, baudRate, Parity.None, 8, StopBits.One); //または //serialPort_ = new System.IO.Ports.SerialPort(portName, baudRate);     (中略)   }   (中略) }

質問者のコメントなどから、System.dllとSystem.IO.Ports.dllで、System.IO.Ports.SerialPortが重複していることを確認しました。

その情報を元に、検索したところ、以下のような手順が詳細されていました。

コンパイルオプションで、-reference:SystemIoPors=System.IO.Ports.dll を指定します。
その上で、以下のように変更。

//using System.IO.Ports; extern alias SystemIoPors; private SystemIoPors::SerialPort serialPort_; serialPort_ = new SystemIoPors::SerialPort(portName, baudRate, Parity.None, 8, StopBits.One);

同じ完全修飾型名を持つ 2 つのアセンブリを参照

申し訳ありませんが、未検証です。

投稿2020/06/24 12:18

編集2020/06/24 15:13
YT0014

総合スコア1750

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

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

Yomihalaalpha

2020/06/24 12:51

System.IO.Ports.SerialPortに変更してみたのですが同様のエラーが出てしまいました。
YT0014

2020/06/24 13:58

返答を確認したため、修正しました。
Yomihalaalpha

2020/06/24 22:28

コンパイルオプションを設定しようとしたのですが、Unityに紐づけされているためか設定画面が見つかりません。質問文に追記します。
YT0014

2020/06/25 00:57

指定画面は、プロジェクトを選択した状態で、右クリックメニューのプロパティで表示されます。ただ、以前のバージョンでは存在した、ビルドでのオプションの指定欄が2019では表示されません。 VsDevCmd.batで設定すると表示されるようになるらしいのですが、指定するオプションの情報が見つかっておらず、やり方が不明です。
Yomihalaalpha

2020/06/25 11:35

わかりました。色々と試してみて、方法が見つかればまた報告します。付き合っていただいてありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問