Гид по технологиям

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

10 min read Arduino Обновлено 02 Jan 2026
Игровой контроллер на Arduino и Unity
Игровой контроллер на Arduino и Unity

О чём эта инструкция

  • Сборка простого контроллера: потенциометр + тактовая кнопка на макетной плате.
  • Настройка Arduino с прошивкой Firmata для связи с Unity.
  • Подключение Unity с помощью плагина Uniduino (встроенный тест-панель).
  • Написание скриптов C# для чтения аналогового значения и управления сферой в сцене.
  • Добавление спауна падающих кубов и взаимодействий.

Важно: все изображения и схемы из оригинала сохранены. Путь к файлам и URL не изменены.


Требования к проекту

  • Arduino Uno или аналогичный микроконтроллер
  • 1 × резистор 10 кОм
  • 1 × моментальная (тактовая) кнопка
  • 1 × потенциометр
  • Провода для макетной платы (hook-up wires)
  • Макетная плата (breadboard)
  • Unity game engine
  • Плагин Uniduino из Unity Asset Store (платный ~30$ на момент написания)
  • Исходный код проекта (если не хотите писать вручную)

Большинство компонентов доступно в комплекте для изучения Arduino. Вы можете усложнить контроллер любым количеством энкодеров, джойстиков и датчиков — в примере используется только потенциометр и кнопка, что идеально для простого аркадного управления.

Сборка контроллера на макетной плате

ALT: Схема и макетная плата с подключённым Arduino и элементами управления — потенциометр и кнопка.

Сборка контроллера на макетной плате

Соберите схему как на изображении ниже: подключите потенциометр к 5V, GND и аналоговому входу (в примере — A5). Кнопку подключите к цифровому пину (в примере — D2), подтянув к GND через 10 кОм или используя внутренний подтягивающий резистор в настройках. Эта простая сборка также подходит для DIY MIDI-контроллера при небольших изменениях.

Собранный контроллер на макетной плате

ALT: Фото макетной платы с подключённым потенциометром и кнопкой, провода ведут к Arduino Uno.

Fritzing-схема с подписями

ALT: Fritzing-диаграмма, показывающая распиновку Arduino и размещение компонентов на макетной плате.

Подготовка Arduino

  1. Подключите Arduino по USB к компьютеру.
  2. В Arduino IDE выберите Tools > Board и Tools > Port, укажите вашу плату и COM-порт.
  3. Откройте пример Firmata: File > Examples > Firmata > StandardFirmata.
  4. Нажмите Upload.

StandardFirmata позволяет Unity (через Uniduino) читать и записывать значения пинов Arduino в реальном времени.

Если вы новичок и установка Arduino вызывает вопросы, рекомендуется пройти краткий вводный курс по Arduino (поиск «Beginner’s Guide to Arduino»). Это ускорит отладку и понимание.

Настройка проекта Unity

  1. Откройте Unity и зайдите Window > Asset Store в редакторе.
  2. Найдите плагин Uniduino и импортируйте его в проект.
    • Примечание: плагин платный, но упрощает работу. Можно обойтись без него, используя SerialPort и собственную реализацию протокола, но это сложнее.
  3. В сцене перетащите префаб Uniduino: Assets > Uniduino > Prefabs > Uniduino.
  4. В панели тестирования Uniduino установите Pin D2 как INPUT и Digital; Pin A5 как ANALOG. Должны появиться значения ваших элементов управления.

Unity Asset Store: Uniduino

ALT: Окно Unity Asset Store с выделенным плагином Uniduino.

Видео от авторов плагина демонстрирует настройку и проверку связи. На Windows иногда требуется перезапустить Unity для корректного захвата COM-порта.

Панель тестирования Uniduino в Unity

ALT: Панель Uniduino в Unity: отображение цифровых и аналоговых пинов и их текущих значений.

Что мы будем управлять

Создадим простую игру: вы управляете сферой внизу экрана, уклоняетесь влево/вправо от падающих кубов. Потенциометр отвечает за горизонтальное перемещение, кнопка — за временное замедление времени (slow-motion).

Создайте новую сцену. Добавьте префаб Uniduino в иерархию.

В иерархии: Create > Sphere. С помощью вкладки Transform поместите её внизу экрана (пример координат показан на изображении).

Inspector: Позиция сферы по X

ALT: Инспектор Unity показывает значение X у Transform для сферы, положение внизу игрового экрана.

Код: подключение Arduino к Unity

Добавим скрипт к сфере. Выделите сферу, затем Add Component > New Script, назовите sphereMover, язык C#. Нажмите Create and Add. Откройте скрипт и вставьте следующий код.

using UnityEngine;
using System.Collections;
using Uniduino;

public class sphereMover : MonoBehaviour
{
    // Заголовки помогают ориентироваться в инспекторе
    [Header("Arduino Variables")]

    // переменная для Arduino
    public Arduino arduino;

    // номер пина потенциометра (публичный — можно задать в инспекторе)
    public int potPinNumber;
    // значение потенциометра (0 - 1023)
    public float potValue;
    // преобразованное значение потенциометра в позицию по X
    public float mappedPot;

    // номер пина кнопки
    public int buttonPinNumber;

    [Header("Sphere Variables")]

    // границы по X, между которыми может двигаться сфера
    public float leftEdge;
    public float rightEdge;

    // Инициализация
    void Start()
    {
        // получаем глобальный объект Arduino и настраиваем пины
        arduino = Arduino.global;
        arduino.Setup(ConfigurePins);
    }

    void ConfigurePins()
    {
        // настраиваем пин потенциометра как аналоговый
        arduino.pinMode(potPinNumber, PinMode.ANALOG);
        // просим Arduino слать изменения аналогового пина (A5 в нашем примере)
        arduino.reportAnalog(5, 1);

        // настраиваем пин кнопки как входной
        arduino.pinMode(buttonPinNumber, PinMode.INPUT);
        arduino.reportDigital((byte)(buttonPinNumber / 8), 1);
    }

    void Update()
    {
        // читаем значение потенциометра с Arduino
        potValue = arduino.analogRead(potPinNumber);

        // далее мы будем ремапить potValue в значение X
    }
}

Обратите внимание на публичные переменные — их удобно задавать в инспекторе. После сохранения скрипта вы увидите новые поля в инспекторе у компонента sphereMover.

SphereMover: пустые поля

ALT: Инспектор Unity показывает компонент sphereMover со множеством пустых полей для настройки.

Заполните номера пинов (например, potPinNumber = 5, buttonPinNumber = 2) и границы leftEdge/rightEdge — это X-координаты, между которыми будет перемещаться сфера.

SphereMover: заполненные переменные

ALT: Инспектор Unity с заполненными значениями пинов и границ движения сферы.

Проверка: «первые признаки жизни»

Добавим одну строку в Update(), чтобы видеть значение потенциометра в реальном времени — это поможет убедиться, что Uniduino слушает нужный порт.

void Update()
{
    // присваиваем значение с Arduino переменной potValue
    potValue = arduino.analogRead(potPinNumber);
}

Проверьте Uniduino в иерархии: укажите Port Name (например, COM4 на Windows). Затем запустите режим Play в Unity. Через несколько секунд potValue должен начать меняться при вращении потенциометра.

Проверка порта Uniduino

ALT: Инспектор Uniduino с полем Port Name, где указан COM-порт Arduino.

Первые сигналы от потенциометра

ALT: Поле potValue в инспекторе Unity меняется в реальном времени при вращении потенциометра.

Если значение не меняется — перепроверьте проводку, выбранный COM-порт и загруженную прошивку StandardFirmata.

Перевод аналогового значения в позицию: Remap

Потенциометр выдаёт значения от 0 до 1023. Нам нужно отобразить этот диапазон на координаты X сцены (например, от leftEdge до rightEdge). Для этого используется вспомогательная функция Remap.

Создайте скрипт ExtensionMethods:

using UnityEngine;
using System.Collections;

public static class ExtensionMethods
{
    // Функция Remap: переводит value из диапазона [from1, to1] в диапазон [from2, to2]
    public static float Remap(this float value, float from1, float to1, float from2, float to2)
    {
        return (value - from1) / (to1 - from1) * (to2 - from2) + from2;
    }
}

Теперь вернитесь в sphereMover и в Update() добавьте ремап и присвоение позиции:

void Update()
{
    potValue = arduino.analogRead(potPinNumber);
    mappedPot = potValue.Remap(0f, 1023f, leftEdge, rightEdge);

    // назначаем X координату сферы
    transform.position = new Vector3(mappedPot, transform.position.y, transform.position.z);
}

Если управление кажется перевёрнутым (повёрнут влево/вправо), поменяйте местами leftEdge и rightEdge в вызове Remap.

Remap: пример использования

ALT: Схема, показывающая, как значение 0..1023 сопоставляется с координатами leftEdge..rightEdge.

Кнопка: замедляем время

Добавьте в Update() проверку состояния кнопки и изменяйте Time.timeScale для эффекта slow-motion:

void Update()
{
    potValue = arduino.analogRead(potPinNumber);
    mappedPot = potValue.Remap(0f, 1023f, leftEdge, rightEdge);
    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;
    }
}

Теперь при нажатии кнопки игровой мир будет замедляться, что даёт шанс увернуться.

Добавляем врагов: падающие кубы

Создайте Cube: Create > 3D Object > Cube. На Cube добавьте компонент Rigidbody (Add Component > Physics > Rigidbody). Установите Drag = 5. В компоненте Box Collider включите Is Trigger — это позволит обрабатывать пересечения без физического отталкивания.

Создайте скрипт collideWithSphere для куба:

using UnityEngine;
using System.Collections;

public class collideWithSphere : MonoBehaviour
{
    void OnTriggerEnter(Collider other)
    {
        Destroy(other.gameObject);
    }
}

Этот скрипт уничтожает объект, с которым столкнулся куб. Далее превратите Cube в префаб (перетащите его в Project panel), удалите куб из сцены.

Создайте пустой объект: Create > Create Empty, назовите Game Manager и добавьте скрипт gameManager:

using UnityEngine;
using System.Collections;

public class gameManager : MonoBehaviour
{
    // префаб куба
    public GameObject cube;

    // параметры спавна
    public int numberToSpawn;
    public float lowestSpawnHeight;
    public float highestSpawnHeight;

    void Start()
    {
        for (int i = 0; i < numberToSpawn; i++)
        {
            Instantiate(cube, new Vector3(Random.Range(-9f, 9f), Random.Range(lowestSpawnHeight, highestSpawnHeight), 0f), Quaternion.identity);
        }
    }

    void Update()
    {

    }
}

В инспекторе Game Manager перетащите префаб cube в поле Cube и задайте параметры спавна. Совет: ставьте lowestSpawnHeight достаточно высоко, чтобы Uniduino успел инициализироваться и игроку дали шанс среагировать.

Game Manager

ALT: Инспектор Unity с компонентом gameManager и полями для префаба куба и параметров спавна.

Финал: игра готова

Запустите сцену. Кубы будут спауниться сверху и падать. Управляйте сферой потенциометром, а в трудные моменты используйте кнопку для замедления времени.

В этом проекте вы:

  • Собрали простой контроллер на Arduino.
  • Использовали StandardFirmata для обмена данными с Unity.
  • Настроили Uniduino для взаимодействия.
  • Написали скрипты для управления объектами и спавна врагов.

Идеи для расширения: добавить звуковую обратную связь, счётчик очков, уровни сложности, новые датчики (гироскоп/акселерометр), или использовать несколько аналоговых входов для дополнительных осей управления.


Частые проблемы и отладка

  • Значения не приходят в Unity:

    • Проверьте COM-порт в Arduino IDE и в Uniduino.
    • Убедитесь, что на Arduino загружен StandardFirmata.
    • Если Uniduino не подключается — закройте другие программы, использующие порт (Arduino IDE Serial Monitor).
  • Потенциометр вращает в обратную сторону:

    • Поменяйте местами leftEdge и rightEdge в Remap.
    • Или переверните проводку потенциометра.
  • Кнопка даёт нестабильные значения:

    • Используйте подтягивающий резистор 10 кОм к VCC или GND, либо включите внутренний pull-up в коде.
    • Проверьте контакт на макетной плате.
  • Unity «теряет» порт после выхода из Play Mode:

    • Иногда требуется перезапустить редактор Unity, чтобы вернуть доступ к COM-порту.

Альтернативные подходы и совместимость

  • Без Uniduino: можно использовать System.IO.Ports.SerialPort в Unity и реализовать собственный протокол обмена данными (чтение аналоговых значений по serial). Потребует доп. программирования и парсинга сообщений.
  • Плагины и библиотеки: помимо Uniduino есть и другие решения (например, Ardity, Uduino). У каждого свои особенности — сравнивайте совместимость с вашей версией Unity.
  • Другие платы: Arduino Leonardo, Micro или платы на базе STM32/Teensy могут выступать в роли HID-устройства и напрямую эмулировать джойстик/клавиатуру. Это даёт другой подход (без Firmata), особенно для проектов, где нужен нативный ввод.
  • Протоколы: рассматривайте OSC или MIDI для взаимодействия с игровыми движками или софтами (подходит, если хотите использовать контроллер в музыкальных проектах).

Ментальные модели и эвристики

  • Разделение ответственности: аппаратная часть (сборка, проводка, прошивка) и программная (Unity, логика). Отлаживайте каждую по отдельности.
  • Слой абстракции: Firmata/Uniduino — это абстракция, которая связывает ваши пины с объектами Unity. Если хотите гибкости и производительности, реализуйте свой протокол на serial.
  • Быстрый цикл разработки: выполняйте минимальные изменения и сразу тестируйте в Play Mode. Это ускоряет поиск ошибок.

Чеклист перед первым запуском

  • Arduino подключён по USB и прошивка StandardFirmata загружена
  • Компоненты на макетной плате подключены согласно схеме
  • Uniduino добавлен в сцену и выбран правильный COM-порт
  • В инспекторе sphereMover заданы номера пинов и границы движения
  • Cube превратил в префаб, Game Manager настроен
  • Все скрипты сохранены и не содержат синтаксических ошибок

Критерии приёмки

  • При вращении потенциометра значение mappedPot меняется и сфера перемещается по оси X.
  • При нажатии кнопки Time.timeScale становится 0.4, при отпускании — 1.0.
  • Кубы падают сверху и уничтожают сферу при касании (или наоборот, в зависимости от логики).
  • Uniduino отображает текущие значения пинов в тест-панели.

Возможные расширения и эксперименты

  • Подключить второй потенциометр для управления скоростью или высотой прыжка.
  • Использовать энкодер вместо потенциометра для бесконечного вращения и дискретного шага управления.
  • Добавить датчики: гироскоп для наклона, ультразвук для внешнего ввода.
  • Реализовать сетевой режим: отправлять данные контроллера по UDP/OSC на другой компьютер.
  • Превратить устройство в MIDI-контроллер: читать значения и слать события MIDI.

Безопасность и приватность

  • Беспокоиться о безопасности в локальном проекте обычно не нужно. Если планируете обмен данными по сети, шифруйте трафик или применяйте проверку подлинности.
  • Не отправляйте данные с устройств на сторонние серверы без явного согласия.

Короткая методология тестирования

  1. Проверка Arduino: загрузить StandardFirmata, открыть Serial Monitor (или проверить COM в IDE).
  2. Подключение Uniduino: убедиться, что выбран COM-порт и тест-панель показывает значения.
  3. Тест логики в Unity: проверять Update() наловченно — сначала вывод potValue в консоль, затем перемещение объекта.
  4. Интеграционное тестирование: убедиться, что управление устойчиво при длительной игре.

Небольшой словарь терминов

  • Firmata — протокол, позволяющий микроконтроллеру передавать данные о пинах по serial.
  • Uniduino — плагин Unity для работы с Arduino через Firmata.
  • Potentiometer (потенциометр) — регулятор сопротивления, дающий аналоговый сигнал.
  • Remap — математическая функция отображения значений из одного диапазона в другой.

Если хотите пойти дальше: когда подход не сработает

  • Если нужен низкий уровень задержки и высокая частота обновления — Firmata + Uniduino может оказаться недостаточно быстрым. В таком случае реализуйте собственную serial-коммуникацию и минимизируйте накладные расходы в сообщениях.
  • Если требуется natively распознаваться ОС как джойстик — используйте платы с поддержкой USB HID (Leonardo, Pro Micro, Teensy).
  • Если контроллер должен работать на мобильном устройстве — рассмотрите Bluetooth (HC-05/06) и приём на стороне мобильного приложения.

Примеры тест-кейсов (приёмочных)

  • ТК1: Потенциометр в крайнее левое положение — сфера становится в координате leftEdge.
  • ТК2: Потенциометр в крайнее правое положение — сфера становится в координате rightEdge.
  • ТК3: Быстрое перемещение потенциометра — перемещение сферы плавное, без «заиканий».
  • ТК4: Нажатие и удержание кнопки — Time.timeScale = 0.4, отпустил — 1.0.

Заключение

Вы создали рабочий прототип контроллера на Arduino и связали его с простой игрой в Unity. Этот пример — отличная отправная точка для проектов с настраиваемыми контроллерами: от арт-инсталляций до соревнований и геймджемов. Экспериментируйте с датчиками, интерфейсами и интерактивностью — возможности почти безграничны.

Если вы собрали похожий проект — поделитесь им в комментариях или на тематических площадках. Интересно увидеть, какие творческие идеи люди реализуют с помощью Arduino и Unity!


Краткий список ресурсов для продолжения изучения:

  • Arduino Official Documentation — справочник по платам и библиотекам.
  • Unity Manual — разделы по Input, Scripting и Prefabs.
  • Uniduino Asset Store — документация и тестовые видео.
Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Bluebugging: как работает и как защититься
Кибербезопасность

Bluebugging: как работает и как защититься

Программирование термостата Google Nest
Умный дом

Программирование термостата Google Nest

Как распознать вредоносные вложения в почте
Кибербезопасность

Как распознать вредоносные вложения в почте

Как понять, взломан ли ваш Wi‑Fi и как защититься
Безопасность Wi-Fi

Как понять, взломан ли ваш Wi‑Fi и как защититься

Защита от инсайдерских атак с программами‑вымогателями
Кибербезопасность

Защита от инсайдерских атак с программами‑вымогателями

Как усилить сигнал Wi‑Fi — полное руководство
Networking

Как усилить сигнал Wi‑Fi — полное руководство