はじめに (対象読者・この記事でわかること)

この記事は、ArduinoやArduino IDEの経験が浅い初心者、そしてUnityで簡単なインタラクティブデモを作りたいクリエイターを対象としています。
本記事を読むことで、以下のことができるようになります。

  • 磁石の磁界を検知できるHallセンサーをArduinoに接続し、磁石が近づいたことを検知できるようになる
  • ArduinoとPC(Unity)がシリアル通信でデータをやり取りする方法を理解できる
  • Unity側で受信したデータを元に、シーン内のCubeオブジェクトを回転・移動させるスクリプトを書くことができる

背景として、IoTデバイスとゲームエンジンを組み合わせた「ハードウェアとソフトウェアのインタラクション」の学習が近年注目されています。磁石というシンプルな入力デバイスで実装できるため、プロトタイプ作成のハードルが低く、教育用途にも最適です。

前提知識

この記事を読み進める上で、以下の知識があるとスムーズです。

  • Arduinoの基本的なプログラミング(スケッチの書き方、シリアルモニタの使い方)
  • Unityの基本操作とC#スクリプトの作成方法
  • シリアル通信の概念(データの送受信、ボーレートの設定)

概要・背景

磁界検知がなぜ有用か

磁石は非接触で入力できる点が大きな魅力です。ゲームコントローラーやインタラクティブ展示物など、手を近づけるだけで反応させたいシーンで有効です。Arduinoは安価で入手しやすく、Hallセンサー(A3144 など)と組み合わせると、磁界の有無をデジタル信号として簡単に取得できます。

使用するハードウェアとソフトウェア

ハードウェア 用途
Arduino UNO センサー情報の取得とPCへのシリアル送信
Hall Effect センサー(A3144) 磁界が検出されたら HIGH、検出されないと LOW を出力
10kΩ プルダウン抵抗 センサー出力を安定させる
USB ケーブル Arduino と PC を接続
PC (Windows/macOS) Unity エディタ実行環境
Unity 2022 以降 3D キューブを制御するゲームエンジン

Arduino IDE はスケッチを書き込むだけでなく、シリアルモニタでデバッグ情報をリアルタイムに確認できるため、開発の初期段階で非常に便利です。

具体的な手順や実装方法

ステップ1 ハードウェアの接続

  1. Hall センサーのピン配置
    * VCC → Arduino の 5V
    * GND → Arduino の GND
    * OUT → デジタルピン 2(プルダウン抵抗 10kΩ を GND と並列に接続)

  2. 配線例

Arduino Hall Sensor ------- ------------ 5V --------> VCC GND --------> GND D2 --------> OUT (10kΩ プルダウンで GND に接続)

  1. 動作確認
    Arduino IDE のシリアルモニタを 9600bps で開き、磁石をセンサーに近づけると「1」、離すと「0」が出力されるか確認します。

ステップ2 Arduino スケッチ作成

Cpp
// ArduinoMagnet.ino const int hallPin = 2; // Hall センサー接続ピン const long baudRate = 9600; // シリアル通信速度 void setup() { pinMode(hallPin, INPUT); Serial.begin(baudRate); } void loop() { int sensorValue = digitalRead(hallPin); // 0 または 1 を文字列として送信 Serial.println(sensorValue); delay(100); // 100ms のポーリング間隔 }

ポイント:

  • digitalRead で HIGH/LOW を取得し、文字列として Serial.println で送信。
  • 送信間隔は 100ms(10Hz)に設定。リアルタイム性が求められない小規模デモに適しています。

ステップ3 Unity 側のセットアップ

  1. 新規プロジェクト作成
    Unity Hub で 3D テンプレートのプロジェクトを作成し、シーンに Cube オブジェクトを配置。

  2. シリアル通信スクリプト作成
    Assets/Scripts/MagnetController.cs に以下を保存。

Csharp
using System.IO.Ports; using UnityEngine; public class MagnetController : MonoBehaviour { public string portName = "COM3"; // Windows の例。macOS は "/dev/tty.usbmodemXXXX" public int baudRate = 9600; private SerialPort sp; private float rotationSpeed = 90f; // 1 秒あたり 90 度 void Start() { sp = new SerialPort(portName, baudRate); sp.ReadTimeout = 50; try { sp.Open(); } catch (System.Exception e) { Debug.LogError("シリアルポートを開けません: " + e.Message); } } void Update() { if (sp != null && sp.IsOpen) { try { string line = sp.ReadLine().Trim(); if (line == "1") { // 磁石が検出されたら回転 transform.Rotate(Vector3.up, rotationSpeed * Time.deltaTime); } } catch (System.TimeoutException) { } } } void OnApplicationQuit() { if (sp != null && sp.IsOpen) sp.Close(); } }

ポイント:

  • portName は OS に合わせて変更してください。
  • ReadLine は改行コードで区切られた文字列を取得します。Arduino 側の println が改行を付与するので対応できます。
  • 磁石が検出された ("1") 時だけオブジェクトを回転させます。
  1. スクリプトのアタッチ
    Cube オブジェクトに MagnetController スクリプトをドラッグ&ドロップし、portName を実際のポートに合わせて設定。

ステップ4 シリアル通信テスト

  • Unity エディタで Play ボタンを押す。
  • 磁石を Hall センサーに近づけると、Cube が回転し始めます。離すと停止します。
  • Unity のコンソールにエラーメッセージが出た場合は、ポート名やボーレートが一致しているか確認してください。

ステップ5 キューブの動作カスタマイズ

  • 回転速度rotationSpeed の値で調整(例: 180 にすれば 1 秒で 180 度)。
  • 移動 に変更したい場合は transform.Translate を使用し、磁石検出時に座標を変えるロジックに置き換えるだけです。
  • 複数センサー を使うと、方向や強度に応じて異なる動きを実装可能です(例: X 軸センサーで上下、Y 軸で左右)。

ハマった点やエラー解決

発生した問題 原因 解決策
Unity がシリアルポートを開けない ポート名が間違っている、または別アプリが占有中 正しいポートを確認し、Arduino IDE のシリアルモニタを閉じる
受信した文字列が空になる Arduino の Serial.println が実行されていない 100ms の delay が短すぎると PC 側の読み取りが追いつかない場合があるので、delay を 200ms に延長
キューブが回転し続ける ReadLine がタイムアウトせずに前回の "1" を保持 line が "1" のときだけ回転し、"0" のときは回転しないロジックを追加(例: else if (line == "0") isRotating = false;

まとめ

本記事では、磁石を近づけたときに Unity の Cube を動かす一連のフローを解説しました。

  • ハードウェア構成:Arduino UNO + Hall センサー + プルダウン抵抗で磁界をデジタル化
  • Arduino 側:センサーデータをシリアルポートに 9600bps で送信するスケッチ
  • Unity 側:シリアルポートからデータを受信し、Cube の回転(または移動)を制御する C# スクリプト

この実装により、磁石というシンプルな入力デバイスでリアルタイムに3Dオブジェクトを制御できる という体感的な学習が可能です。今後は、磁界の強度に応じた速度変化や、複数のセンサーで 3 軸制御を行うといった発展的なテーマにも挑戦できるでしょう。

参考資料