Создание игрового контроллера на Arduino и Unity

Краткое содержание
- Аппаратные компоненты и схема сборки
- Настройка Arduino и загрузка Firmata
- Подключение Unity и Uniduino
- Скрипты для управления шаром и генерации препятствий
- Отладка, улучшения и альтернативы
Для этого проекта понадобится
- Arduino или совместимый микроконтроллер
- 1 х 10k Ом резистор
- 1 х кнопка с фиксацией (momentary switch)
- 1 х потенциометр
- Соединительные провода
- Макетная плата (breadboard)
- Unity game engine
- Плагин Uniduino из Unity Asset Store (платно, $30)
- Исходный код проекта (прилагается, плагин в архив не входит)
Большинство компонентов доступны в стартовом наборе Arduino. Для примера мы используем потенциометр и кнопку — достаточно для простого аркадного управления.

Сборка контроллера
Соберите схему на макетной плате, как на изображении выше. Это стандартная конфигурация: потенциометр подключён к аналоговому входу, кнопка — к цифровому входу с подтяжкой к питанию через резистор. Такая же схема легко адаптируется под MIDI- или другие DIY-проекты.

Внимание: подпишите на макетной плате номера используемых пинов. Это облегчит настройку в Unity.
Подготовка Arduino
- Подключите Arduino к компьютеру через USB.
- В Arduino IDE выберите Tools > Board и Tools > Port, чтобы указать плату и порт.
- Откройте пример Firmata: File > Examples > Firmata > StandardFirmata и загрузите скетч в плату.
Если вы новичок в Arduino, посмотрите базовые руководства по загрузке скетчей и установке драйверов.
Настройка проекта в Unity
- Откройте Unity и перейдите Window > Asset Store.
- Найдите плагин Uniduino и установите его в проект. Плагин позволяет читать и писать значения пинов Arduino прямо в Unity. На момент написания плагин платный (в долларах США).

- Перетащите префаб Uniduino из Assets > Uniduino > Prefabs в Hierarchy.
- В панели префаба проверьте Port Name и укажите порт вашей платы (например COM4 в Windows). Если поле пустое, плагин не подключится.
Важно: иногда на Windows требуется перезапуск редактора Unity после установки плагина.
Проверка входов в тестовой панели Uniduino
Откройте тестовую панель плагина и установите Pin D2 как INPUT/Digital, а Pin A5 как ANALOG. Если всё настроено верно, вы увидите изменяющиеся значения при вращении потенциометра и нажатии кнопки.
Что мы будем контролировать
Мы создадим простую игру: шар, которым двигают влево и вправо при помощи потенциометра. Кнопка будет замедлять время, чтобы временно облегчить уклонение от падающих кубов.
Создайте новую сцену. Перетащите префаб Uniduino в Hierarchy. Создайте объект Sphere через Create > 3D Object > Sphere и переместите его в нижнюю часть экрана, используя Transform.
Скрипт управления сферой — подготовка
С выделенным объектом Sphere в инспекторе нажмите Add Component > New Script. Назовите его sphereMover, выберите C# и нажмите Create and Add. Откройте скрипт и вставьте следующий код (полный рабочий вариант):
using UnityEngine;
using System.Collections;
using Uniduino;
public class sphereMover : MonoBehaviour
{
[Header("Arduino Variables")]
public Arduino arduino;
// Номера пинов (настраиваются в инспекторе)
public int potPinNumber;
public float potValue;
public float mappedPot;
public int buttonPinNumber;
[Header("Sphere Variables")]
public float leftEdge;
public float rightEdge;
void Start()
{
arduino = Arduino.global;
arduino.Setup(ConfigurePins);
}
void ConfigurePins()
{
arduino.pinMode(potPinNumber, PinMode.ANALOG);
arduino.reportAnalog(5, 1);
arduino.pinMode(buttonPinNumber, PinMode.INPUT);
arduino.reportDigital((byte)(buttonPinNumber / 8), 1);
}
void Update()
{
// Чтение значения потенциометра
potValue = arduino.analogRead(potPinNumber);
// Переводим диапазон 0-1023 в координаты сцены
mappedPot = potValue.Remap(0, 1023, leftEdge, rightEdge);
// Назначаем X-координату шарика
transform.position = new Vector3(mappedPot, transform.position.y, transform.position.z);
// Кнопка замедляет время
if (arduino.digitalRead(buttonPinNumber) == 1)
{
Time.timeScale = 0.4f;
}
else Time.timeScale = 1.0f;
}
}Обратите внимание: в коде используются публичные поля, их удобно редактировать через инспектор Unity.
Расширение: метод Remap
Чтобы корректно отображать значения потенциометра в координатах Unity, мы создадим утилитный скрипт ExtensionMethods с методом Remap. Создайте C#-скрипт ExtensionMethods и вставьте код:
using UnityEngine;
using System.Collections;
public static class ExtensionMethods {
public static float Remap (this float value, float from1, float to1, float from2, float to2)
{
return (value - from1) / (to1 - from1) * (to2 - from2) + from2;
}
}Метод Remap переводит число из одного числового диапазона в другой. Это стандартная техника, полезная для всех аналоговых входов.
Первые признаки жизни
Добавьте potPinNumber и buttonPinNumber в инспекторе по номерам, которые вы использовали на макетной плате. Заполните leftEdge и rightEdge значениями X-координат, соответствующими краям платформы. Запустите сцену кнопкой Play. Если соединение установлено, в инспекторе будете видеть изменяющиеся значения potValue и mappedPot.

Если значения не меняются, проверьте порт в настройках префаба Uniduino и убедитесь, что в Arduino загружен StandardFirmata.
Перемещение сферы
Потенциометр отдаёт значения от 0 до 1023. Эти числа нужно отобразить в координате X сцены. Именно для этого и нужен Remap: сопоставление диапазонов. Пример использования:
mappedPot = potValue.Remap(0, 1023, leftEdge, rightEdge);Если направление управления обратное (крутите вправо — X уменьшается), поменяйте местами leftEdge и rightEdge при вызове Remap.

Применение кнопки
Кнопка будет замедлять игру. Код уже добавлен в Update: при чтении 1 из цифрового входа мы устанавливаем Time.timeScale в 0.4, иначе — 1.0. Экспериментируйте с коэффициентом замедления для более удобного геймплея.
Препятствия и столкновения
Создайте Cube через Create > 3D Object > Cube. Добавьте компонент Rigidbody и установите Drag в 5. В Box Collider включите Is Trigger.
Создайте скрипт collideWithSphere и вставьте:
using UnityEngine;
using System.Collections;
public class collideWithSphere : MonoBehaviour
{
void OnTriggerEnter(Collider other)
{
Destroy(other.gameObject);
}
}Этот скрипт уничтожает объект, с которым происходит столкновение. Примените его к префабу куба.
Создание менеджера спавна
Создайте пустой объект и назовите его Game Manager. Добавьте скрипт gameManager:
using UnityEngine;
using System.Collections;
public class gameManager : MonoBehaviour {
public GameObject cube;
public int numberToSpwan;
public float lowestSpawnheight;
public float highestSpawnheight;
void Start ()
{
for (int i = 0; i < numberToSpwan; i++)
{
Instantiate(cube, new Vector3(Random.Range(-9, 9), Random.Range(lowestSpawnheight, highestSpawnheight), 0), Quaternion.identity);
}
}
void Update ()
{
}
}Перетащите префаб куба в поле Cube в инспекторе Game Manager и настройте количество и высоты спавна. Убедитесь, что низкие значения высоты настройки достаточно велики, чтобы дать время Uniduino инициализироваться.
Готовый проект
Нажмите Play. Кубы будут спавниться над шаром и падать. Управляйте шаром потенциометром и замедляйте время кнопкой, чтобы уклоняться.
В проекте вы:
- Собрали простой контроллер на Arduino
- Настроили связь Arduino ⇄ Unity через Uniduino
- Реализовали управление и простую механику игры
Советы по улучшению аппаратной части
- Используйте более надёжные тактильные кнопки с антидребезгом.
- Добавьте светодиоды для обратной связи (например, индикация подключения).
- Замените макетную плату на печатную плату для окончательной сборки.
- Поставьте потенциометр с ограничителями хода, чтобы избежать дребезга на крайних значениях.
Отладка и частые проблемы
Важно: если в инспекторе Unity не появляются значения с Arduino — проверьте: порт префаба Uniduino, загружен ли StandardFirmata на плату, не занят ли порт другой программой. На Windows иногда помогает перезапуск Unity.
Проверка по шагам:
- Подключите плату к компьютеру и откройте Arduino IDE. Убедитесь, что плата реагирует и выбран правильный порт.
- Загрузите StandardFirmata в плату.
- В Unity убедитесь, что префаб Uniduino содержит порт и подключён.
- В тестовой панели Uniduino включите отчётность аналоговых и цифровых пинов.
- Проверьте проводку на макетной плате.
Техника отладки аппаратуры:
- Измерьте мультиметром напряжение на выводах потенциометра при разных положениях.
- Подключите светодиод или серийный вывод для мониторинга состояния.
Расширенные приёмы обработки входа
- Фильтрация (low-pass): для плавного движения сферы можно применить экспоненциальное сглаживание.
- Мёртвая зона: игнорируйте небольшие колебания вокруг центрального положения, чтобы избежать дрожания.
- Антидребезг для кнопок: программная задержка 10–50 мс после изменения состояния.
- Калибровка: добавьте UI-панель в игре для тонкой настройки leftEdge/rightEdge и инверсии управления.
Пример простого сглаживания в Update:
float smoothSpeed = 0.1f;
float currentX = transform.position.x;
float targetX = mappedPot;
float newX = Mathf.Lerp(currentX, targetX, smoothSpeed);
transform.position = new Vector3(newX, transform.position.y, transform.position.z);Альтернативы Uniduino и варианты реализации
- Firmata + собственная реализация на C# через SerialPort. Это бесплатно, но требует больше кода и обработки протокола.
- Использовать промежуточный Node.js-сервер с библиотекой Johnny-Five, который пересылает данные в Unity по WebSocket.
- Заменить Arduino Uno на Nano, Leonardo, Mega или ESP32. Многие платы совместимы с Firmata, но ESP32 может потребовать другой прошивки.
Плюсы Uniduino: простота, интеграция в редактор. Минусы: платность и ограниченная гибкость по сравнению с низкоуровневой Serial-реализацией.
Аппаратная совместимость и миграция
| Плата | Firmata поддерживается | Примечания |
|---|---|---|
| Arduino Uno | Да | Самый распространённый вариант |
| Arduino Nano | Да | Компактнее, совместим по пинам |
| Arduino Mega | Да | Больше пинов, полезно для сложных проектов |
| Arduino Leonardo | Да | Поддержка HID может быть полезна |
| ESP32 | Частично | Требует кастомной прошивки, Firmata не всегда готов из коробки |
| Raspberry Pi | Нет | Лучше подключать через USB/Serial при помощи отдельного микроконтроллера |
При миграции обратите внимание на нумерацию аналоговых пинов и их обозначение в Uniduino/Firmata.
Безопасность и приватность
Проект не обрабатывает личные данные. Тем не менее:
- Защищайте свою среду разработки от посторонних устройств, особенно при использовании общих USB-портов.
- Не передавайте приватные данные через незащищённые каналы при расширении проекта в сеть.
Малые идеи и альтернативные применения
- Превратить контроллер в MIDI-устройство (использовать MIDI-bridge или преобразовать данные в MIDI-сообщения).
- Сделать контроллер для физической клавиатуры или аркадной панели для локального эмулятора.
- Использовать несколько потенциометров и кнопок для управления многими параметрами игры.
Шаблон чек-листа перед запуском сцены
- Arduino подключён и виден в Arduino IDE
- Загружен StandardFirmata
- Uniduino префаб в сцене и настроен порт
- potPinNumber и buttonPinNumber заполнены
- leftEdge и rightEdge заданы корректно
- Cube префаб настроен и помещён в Game Manager
- Проверена физическая проводка на макетной плате
Критерии приёмки
- Шар перемещается влево/вправо при вращении потенциометра
- Кнопка замедляет время в игре
- Кубы спавнятся и уничтожают шар при столкновении
- Значения с Arduino отображаются в инспекторе Unity
Тест-кейсы
- Подключение: Arduino подключён, StandardFirmata загружен, Unity показывает значения аналогового пина при вращении потенциометра.
- Управление: при полном повороте влево mappedPot == leftEdge, при полном вправо mappedPot == rightEdge.
- Кнопка: при нажатии Time.timeScale уменьшается до 0.4; при отпускании — возвращается к 1.0.
- Столкновение: при касании куба шар уничтожается.
Руководство по восстановлению после ошибок
Если Unity не читает пины:
- Закройте Unity и Arduino IDE.
- Отключите Arduino и подключите снова.
- Перезапустите Unity и проверьте порт у префаба Uniduino.
- Если всё равно не работает — загрузите StandardFirmata заново.
Роли и обязанности в команде
- Hardware Tinkerer: отвечает за проводку, пайку, выбор компонентов.
- Developer: пишет скрипты, настраивает Uniduino и Unity.
- Designer: делает уровни, настраивает спавн и игровые параметры.
- QA: прогоняет тест-кейсы и заполняет чек-лист.
Мини-методология для быстрых прототипов
- Соберите минимальную схему (потенциометр + кнопка).
- Загрузите Firmata и проверьте через Arduino IDE.
- Быстро подключите Uniduino и проверьте значения.
- Сделайте минимальный контроллер в Unity и протестируйте управление.
- Итеративно добавляйте функциональность: сглаживание, спавн, столкновения.
Модель зрелости проекта
- MVP: Один вход (потенциометр) и одна механика (движение).
- V1: Добавлена кнопка, базовые препятствия.
- V2: Доп. входы, UI для калибровки, сохранение настроек.
- Production: Плата в корпусе, стабильный протокол, упаковка для распространения.
Пример текста для анонса проекта (100–200 слов)
Создан простой и расширяемый контроллер на Arduino для Unity. С помощью одного потенциометра и кнопки мы реализовали управление шаром и механику замедления времени. Руководство включает сборку схемы, загрузку StandardFirmata, подключение Uniduino и примеры скриптов для управления объектами Unity. Подойдёт как учебный проект и как основа для более сложных интерфейсов — от MIDI-контроллеров до кастомных геймпадов. Делитесь своими модификациями в комментариях!
Предложения для соцсетей
OG title: Создайте игровой контроллер на Arduino и Unity OG description: Пошаговое руководство по сборке контроллера на Arduino и интеграции с Unity. Код, схема и советы по отладке.
Глоссарий (1 строка на термин)
- Firmata: протокол для управления микроконтроллером через сериал.
- Uniduino: Unity-плагин для связи с Arduino.
- Потенциометр: переменный резистор для аналогового ввода.
Заключение
Этот проект показывает, как легко можно соединить аппаратную и программную части. Начните с малого: один вход, одна механика. Затем итеративно усложняйте систему: добавляйте кнопки, датчики, свет, обратную связь. Аппаратные прототипы — отличный способ расширить границы игрового дизайна.
Если вы реализовали модификации — поделитесь ими в комментариях или на форумах проекта. Удачи и творческих идей!


Похожие материалы
Как сделать скриншот в приложении Android
Поиск в реестре Windows с RegScanner
Как сделать фон изображения прозрачным
Как увидеть скрытый контент на Facebook фан‑страницах
Warzone не запускается в Windows — как исправить