Unity × ROS 2連携完全ガイド-試行錯誤の全記録
Unity 6上のデジタルツイン(mechArm 270 M5)を、Mac上のROS 2(Humble)から遠隔操作するシステムの構築に成功しました。
※本プロジェクトの目的:実機「mechArm 270 M5」の制御を通じて、AIの判断をいかに物理的な動きへ変換するか。そのロボット制御の仕組みを理解するプロセスを記録・検証するものです。
Unity側の通信基盤:ROS TCP Connectorの導入

まず、UnityとROSの橋渡し役となる公式パッケージを導入しました。
手順: Package Managerから
ROS TCP Connectorをインストール。設定:
Robotics➔ROS Settingsを開き、通信ルールを決定。
最初の失敗:Protocolの不一致
初期設定が「ROS1」になっていたため、ROS 2との通信が成立しませんでした。
解決策: 明示的に「ROS2」へ切り替えることで解決。
Mac側のエンドポイント構築:ワークスペースの迷路
ROS 2側でUnityからのデータを受け取る窓口を作るプロセスです。
手順: 専用ワークスペース
unity_wsを作成し、ROS-TCP-Endpointをビルド。
ビルドの壁:コマンド未検出
colcon buildを実行した際、command not found: colconエラーが発生。解決策: Conda環境(ros_env)に
colconをインストールし、環境をアクティベートすることで解決。
IPアドレスの疑問
サーバーが 0.0.0.0 で立ち上がり、Unityの設定 127.0.0.1 と食い違って見えた。
学び: 0.0.0.0 は「すべての接続を待つ」状態であり、自分自身の 127.0.0.1 からのアクセスも包含されるため問題ないという知見を得ました。
ロボットに「耳」を付ける:Subscriberの実装
通信がつながっても(HUDが青くなっても)、ロボットが命令を理解できなければ動きません。
課題: ROS 2のトピック /arm_joints を購読するスクリプトが必要。
スクリプト作成の三重苦
名称エラー: クラス名にスペース(Joint State Subscriber)を入れてしまい、作成ボタンが押せない。
iCloudの罠: プロジェクトがiCloud同期フォルダにあったため、
DirectoryNotFoundExceptionで保存に失敗。UIの変化: Unity 6ではC# ScriptがMonoBehaviour Scriptという名前に変わっていた。
解決策: スペースを抜き、iCloudを避け、新しいメニューから
JointStateSubscriberを作成。
6つの関節の「配線」

プログラム(脳)と3Dモデル(体)を物理的に紐付ける作業です。
設定:
JointStateSubscriberのJoint Bodies配列を「Size: 6」に設定。手順: Hierarchyから
link1〜link6を、InspectorのElement 0 〜 5 へ順番にドラッグ&ドロップ。
これにより、ROSからの1番目の角度がlink1に伝わる仕組みが完成しました。
成功の瞬間:Hello, Robot!

ターミナルから以下のコマンドを打ち込んだ瞬間、Unity内のロボットが生命を宿したように回転しました。
ros2 topic pub --once /arm_joints sensor_msgs/msg/JointState "{name: ['link1', ...], position: [1.0, 0.0, ...]}"結果: ターミナルに publishing #1 と表示され、Unity内のアームが正確に約57度(1.0ラジアン)傾きました。
さらに、複雑なポーズの実現
ターミナルから複数関節の角度指定コマンドを送信しました。
ros2 topic pub --once /arm_joints sensor_msgs/msg/JointState "{name: ['link1', ...], position: [-1.0, 0.5, 0.8, -0.5, 1.0, 0.5]}"結果: ターミナルに publishing #1 と表示され、Unity内のロボットが指定通りの複雑なポーズをピタリと再現。Unity HUDも青く輝き、完全な同期を確認しました。
本日の教訓
HUDの色は正直: 青ければ通信はOK。動かないならスクリプトを疑う。
環境のsourceは絶対: 新しいターミナルを開くたびに
conda activateとsource setup.zshを忘れないこと。iCloudは開発の敵: パスエラーが出る場合は、ローカルフォルダへ移動するのが鉄則。
ターミナルのエラーについて

[ERROR] Exception: No more data available
このエラーは、通信が突然途切れたことを示しています。
原因: 主にUnityの再生ボタン(▶︎)を停止したときに発生します。
仕組み: ROS側のサーバー(Mac)はUnityからデータが送られてくるのをずっと待っていますが、Unityを止めると通信用の「管(ソケット)」が急に閉じられます。ROS側が「次のデータを読もうとしたら、もうデータが空っぽ(No more data)だった!」と驚いて出しているエラーです。
結論: Unityの再生を止めたときに出るものであれば、完全に無視して大丈夫です。
[INFO] Disconnected from 127.0.0.1
これはエラーではなく、接続が切れましたというただの通知です。
意味: 上記のエラーに伴い、Unity(127.0.0.1)との通信が終了したことを記録しています。これも、Unityを停止すれば必ず出るメッセージです。
[WARN] Publisher already registered...
これが一番長く、難しそうに見える警告(黄色い文字)ですね。
意味: 同じ名前の送信役(Publisher)が、すでにROSの世界に登録されていますよという警告です。
原因: ROS 2では、通信の参加者リストがMacの中で管理されています。Unityを停止➔再生と素早く繰り返すと、ROS側で前のUnityの登録情報が消える前に新しいUnityの登録が来てしまい、名前が重複するために発生します。
解決策: 数秒待ってから再生するか、気になる場合はMac側のサーバー(ターミナル)を一度
Ctrl + Cで止めてから起動し直すと消えます。基本的には無視しても動作に支障はありません。
