Как сделать пользовательский игровой контроллер с Arduino и Unity

Вы когда-нибудь хотели создать свой собственный игровой контроллер? Это проще, чем вы думаете!

В этом коротком проекте мы создадим простой пользовательский игровой контроллер для использования с игровым движком Unity. Этот контроллер будет работать на Arduino Uno, хотя вы могли бы использовать одну из многих альтернатив

там для этого проекта тоже. Мы также создадим базовую игру, в которой вы будете использовать свой контроллер, чтобы избежать падающих объектов и замедлить время.

Для этого проекта вам понадобится

  • Arduino или аналогичный микроконтроллер
  • 1 х 10 кОм резистор
  • 1 х мгновенный выключатель
  • 1 х Потенциометр
  • Монтажные провода
  • Макет
  • Игровой движок Unity
  • Плагин Uniduino от Unity Asset Store ($ 30)
  • Полный код проекта, если вы не хотите его записывать (не включает плагин Uniduino)

Большинство из этих вещей доступны в стартовом наборе Arduino. Если у вас нет стартового комплекта, ознакомьтесь с нашим руководством по выбору лучших

один для тебя.

Вы можете сделать свой контроллер настолько сложным, насколько пожелаете, хотя для этого примера мы настроим потенциометр и кнопку, которые идеально подходят для управления простой аркадной игрой.

Макет нестандартного контроллера 670

Сборка вашего контроллера

Установите макет и Arduino, как показано на рисунке ниже. Это то, что мы будем использовать в качестве игрового контроллера, хотя вы можете использовать почти ту же самую настройку, что и у миди-контроллера DIY.

тоже!

Fritzing Диаграмма Аннотированный

Подготовка вашего Arduino

Как только у вас все будет подключено, подключите Arduino через USB. В Arduino Software IDE отправляйтесь в Инструменты> Доска а также Инструменты> Порт выбрать, какой микроконтроллер и порт вы используете. В состав Arduino IDE входит эскиз, который нам нужен, и вы можете найти его в Файл> Примеры> Firmata> StandardFirmata. Нажмите Загрузить, и вы будете готовы к работе.

Если вы новичок в Arduino, и ваша голова слегка тает, ознакомьтесь с нашим руководством для начинающих

чтобы помочь вам хорошо поговорить с вашим компьютером.

Настройка вашего проекта Unity

В Unity откройте Окно> Магазин активов получить доступ к хранилищу активов Unity из редактора Unity. Найдите Asset Store для плагина Uniduino. Этот плагин позволит вам получать и отправлять данные с ваших контактов Arduino в Unity. Плагин на момент написания стоит 30 долларов. Можно сделать этот проект, не покупая плагин, хотя он несколько сложнее, и вы можете найти плагин более удобным со всех сторон.

Unity Asset Store Uniduino

Это видео от создателей плагина проведет вас через процесс тестирования, все работает, вместе с первоначальной настройкой. Обратите внимание, что вам также может понадобиться сбросить редактор Unity в Windows.

Мы можем использовать эту же тестовую панель для тестирования нашего контроллера. Установите контакт D2 на ВХОД и Цифровой. Далее вниз установите контакт A5 на ANALOG. Теперь ваш потенциометр и кнопка должны отображать значения на экране рядом с их номерами контактов. Прогресс!

Тест Uniduino

Теперь, чтобы сделать то, что мы можем контролировать

Итак, у нас есть контроллер, но что мы будем контролировать? Ну, возможности безграничны, но на сегодня мы создадим очень простую игру в уклонение, чтобы протестировать нашу новую систему управления. Мы довольно быстро перейдем к настройке игры, поэтому, если вы совершенно не знакомы с движком Unity, вы можете найти наше Руководство для начинающих по программированию игр Unity.

полезно, чтобы получить ваши ориентиры.

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

Создайте новую сцену и перетащите префаб Uniduino из Активы> Uniduino> Сборные в вашу иерархию и перетащите сборник Uniduino в иерархию. Нам это нужно для разговора между нашей игрой и контроллером.

В иерархии Unity нажмите Создать> Сфера и используйте вкладку «Преобразование» в Инспекторе, чтобы переместить ее в нижнюю часть игрового экрана.

Инспектор Сфера X Позиция

Пришло время получить кодирование

Теперь добавим немного кода на эту вечеринку. Выбрав сферу в Иерархии, нажмите Добавить компонент> Новый скрипт в нижней части окна инспектора. Назови это sphereMover и выберите С Sharp из выпадающего меню. Нажмите Создать и добавить и скрипт будет добавлен в GameObject. Дважды щелкните по нему, чтобы открыть скрипт и введите этот код:

using UnityEngine;
using System.Collections;
using Uniduino;
public class sphereMover : MonoBehaviour
{
//Headers aren't scrictly neccesary, but they make life easier back in the Inspector.
[Header("Arduino Variables")]
//we need to declare the Arduino as a variable
public Arduino arduino;
//we need to declare an integer for the pin number of our potentiometer,
//making these variables public means we can change them in the editor later
//if we change the layout of our arduino
public int potPinNumber;
//a float variable to hold the potentiometer value (0 - 1023)
public float potValue;
//we will later remap that potValue to the y position of our capsule and hold it in this variable
public float mappedPot;
//public int for our button pin
public int buttonPinNumber;
[Header("Sphere Variables")]
//variables to hold the values we noted earlier for the sides of our screen
public float leftEdge;
public float rightEdge;
// Use this for initialization
void Start ()
{//and initialize we shall, starting with the Arduino Variable.
//we are only using one arduino, so we can use Arduino.global to grab it.
arduino = Arduino.global;
arduino.Setup(ConfigurePins);
}
void ConfigurePins()
{
//configure the Arduino pin to be analog for our potentiometer
arduino.pinMode(potPinNumber, PinMode.ANALOG);
//Tell the Arduino to report any changes in the value of our potentiometer
arduino.reportAnalog(5, 1);
//configure our Button pin
arduino.pinMode(buttonPinNumber, PinMode.INPUT);
arduino.reportDigital((byte)(buttonPinNumber / 8), 1);
}
}

Найдите минутку, чтобы прочитать комментарии к коду. Пока что мы объявили некоторые переменные для нашего Arduino, его выводов и нашей Сферы. Мы также использовали
Методы Start и ConfigurePins для инициализации нашего Arduino во время выполнения. Давайте сохраним наш скрипт, вернемся в редактор Unity и посмотрим, что изменилось.

Скрипт Sphere Mover с пустыми переменными

Теперь мы можем видеть наши открытые переменные в окне инспектора. Давайте посмотрим, что мы можем сделать на этом этапе, чтобы помочь нам позже. Мы знаем, какие булавки мы используем на Arduino из нашей сборки ранее, мы можем ввести их. Мы также знаем из нашего эксперимента ранее, как далеко мы хотим, чтобы наша сфера могла перемещаться влево и вправо, чтобы она не падала с экрана. Давайте введем эти значения сейчас.

Скрипт Sphere Mover с переменными

Первые признаки жизни

Пришло время увидеть значения из нашего Arduino в редакторе Unity. На данный момент мы можем добавить одну строку кода в функцию обновления нашего сценарияphere Mover и снова сохранить сценарий.

void Update ()
{
//We assign the value the arduino is reading from our potentionmeter to our potValue variable
potValue = arduino.analogRead(potPinNumber);
} 

Теперь, когда у нас есть переменная potValue, обновляемая каждый кадр, мы можем видеть ее значение в реальном времени в Инспекторе Unity. Прежде чем мы проведем тестирование, сейчас самое время проверить, подключается ли подключаемый модуль Uniduino к нужному порту. Нажмите на Uniduino в Heirarchy и проверьте его имя порта в инспекторе. Если он пуст, введите правильный номер порта для вашего Arduino. В данном случае это был COM4, ​​хотя он может отличаться для вас. Проверьте с помощью Arduino IDE, если вы не уверены.

Порт проверки Uniduino правильный

Выберите сферу в иерархии и нажмите кнопку «Воспроизвести» в верхней части экрана. Системе требуется несколько секунд для инициализации, после чего вы должны увидеть изменение переменной Pot Value в инспекторе при перемещении потенциометра.

Признаки Жизни 2

Теперь мы говорим! Ну, строго говоря, Unity и Arduino говорят, но кто считает? Если вы зашли так далеко и не видите изменения значения в инспекторе, проверьте шаги настройки и убедитесь, что для вашего Arduino выбран правильный порт.

Давайте переместим эту сферу

Теперь, когда у нас обновлена ​​переменная potValue, мы хотим использовать это значение для перемещения нашей сферы. Когда потенциометр полностью направлен влево, мы хотим, чтобы сфера находилась с левой стороны экрана, и наоборот. Объекты в Unity расположены в точке векторного пространства, определяемой значениями его Transform.position. На изображении ниже, где сфера находится в самой дальней точке слева, которую мы хотели бы видеть, вы можете видеть, что ее вектор положения равен 9,5, -4, 0.

Пример преобразования 670

Мы хотим повлиять на положение X сферы. К сожалению, использование значений из нашего потенциометра напрямую не будет работать, так как, когда потенциометр находится полностью влево, он дает значение 0 — что поместит нашу сферу прямо в середину экрана. С другой стороны, верхнее значение потенциометра, 1023, поместило бы куб справа от нашего экрана. Не полезно. Здесь нам нужна математика.

Почему математика, когда единство сделает это для вас?

Для тех из вас, кто боится пялиться на листок бумаги, покрытый бессмысленными числами (хотя есть несколько отличных сайтов

это может помочь вам выучить математику), не бойтесь. Нам нужен способ, чтобы наши значения потенциометра соответствовали положению X нашей сферы. К счастью, мы можем использовать Метод расширения.

Метод расширения — это сценарий, который выполняет определенную работу за нас. В этом случае мы даем ему значения, которые у нас есть, и он возвращает их сопоставленные друг другу, готовые для использования в нашем sphereMover скрипт. В верхней части панели «Проект» нажмите Создать> C # Script и назовите его ExtensionMethods. Введите приведенный ниже код в скрипт:

using UnityEngine;
using System.Collections;
public static class ExtensionMethods {
//our handy dandy Remapper function
public static float Remap (this float value, float from1, float to1, float from2, float to2)
{
return (value - from1) / (to1 - from1) * (to2 - from2) + from2;
}
}

Сохраните сценарий и вернитесь к вашему сценариюphereMover. Теперь мы можем использовать эту функцию Remap в нашем скрипте ExtensionMethods в нашей функции Update, чтобы преобразовать наши значения потенциометра в используемые значения в нашей игре. В разделе, где мы только что присвоили переменную potValue, введите следующее:

Функция переназначения

Подсказка показывает нам, что наш Remap принимает два набора значений From и To и отображает их вместе. Мы можем ввести наши ценности в это.

mappedPot = potValue.Remap(0, 1023, leftEdge, rightEdge);

Сохраните ваш скрипт, вернитесь в редактор Unity и нажмите кнопку воспроизведения. Теперь вы должны увидеть, что переменная Mapped Pot изменяется при перемещении потенциометра, чтобы соответствовать значениям, которые мы определили для наших левого и правого краев. Найдите минутку, чтобы расслабиться и поблагодарить ваш скрипт ExtensionMethods. Не калькулятор в поле зрения.

Сопоставленный горшок

Примечание: если вы замечаете, что ваши значения поменялись местами, поэтому, когда ваш потенциометр полностью направлен, вы получаете отрицательное значение для вашей переменной Mapped Pot, возможно, ваш потенциометр настроен неправильно. К счастью, вы можете это исправить, не выполняя никаких изменений. Вы можете просто переключать значения при их переназначении:

Переключить Remap

Теперь у нас наконец есть полезные значения. Теперь осталось только присвоить эти значения позиции X нашей сферы:

//Assign the mapped pot value to the sphere's x position
transform.position = new Vector3(mappedPot, transform.position.y, transform.position.z);

Сохраните ваш скрипт, вернитесь в редактор Unity и нажмите play. Теперь вы сможете перемещать свою сферу влево и вправо, используя свой потенциометр!

Положить кнопку на работу

Теперь, когда наша сфера движется, разве не было бы неплохо иметь способ немного замедлить ситуацию, когда мы окажемся в затруднительном положении? Мы собираемся использовать нашу кнопку, чтобы замедлить время в нашей игре. Откройте сценарийphereMover и добавьте этот код в функцию обновления.

//if Unity detects the button is being pressed, the time scale slows down
if (arduino.digitalRead(buttonPinNumber) == 1){
Time.timeScale = 0.4f;
}
else Time.timeScale = 1.0f;

Теперь у нас есть механика нашей игры, давайте добавим некоторые препятствия! Мы собираемся использовать естественного врага сферы, куба. В иерархии нажмите Создать> 3D-объект> Куб. В инспекторе куба Добавить компонент> Физика> Твердое тело. Установите для параметра «Перетаскивание» жесткого тела значение 5. Также в компоненте «Box Collider» в Инспекторе выберите «Триггер». Это позволит нам обнаруживать столкновения с нашей Сферой.

Создайте скрипт на кубе и назовите его collideWithSphere, откройте скрипт и удалите функции Start и Update, так как в этот раз они нам не понадобятся. Введите этот код:

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

OnTriggerEnter отправляет сообщение всякий раз, когда триггерный коллайдер попадает в другой коллайдер. В этом случае мы говорим, чтобы он уничтожил все, к чему прикасался. Сохраните скрипт и вернитесь в редактор Unity. Перетащите куб из иерархии на панель «Проект». Вы заметите, что текст куба в иерархии стал синим. Это потому, что мы создали сборный дом и сохранили его в нашем проекте. Удалите свой куб из иерархии сейчас.

Все, что нам сейчас нужно, это скрипт для порождения кубов. В иерархии нажмите Создать> Создать пустой, и переименуйте его в Game Manager в Инспекторе и добавьте в него скрипт с именем gameManager. Откройте скрипт и добавьте этот код:

using UnityEngine;
using System.Collections;
public class gameManager : MonoBehaviour {
//a variable to hold the prefab we want to spawn
public GameObject cube;
//we want some variables to decide how any cubes to spawn
//and how high above us we want them to spawn
public int numberToSpwan;
public float lowestSpawnheight;
public float highestSpawnheight;
// Use this for initialization
void Start ()
{
for (int i = 0; i < numberToSpwan; i++)
{
Instantiate(cube, new Vector3(Random.Range(-9, 9), Random.Range(lowestSpawnheight, highestSpawnheight), 0), Quaternion.identity);
}
}
// Update is called once per frame
void Update ()
{
}
}

Сохраните скрипт. Вернувшись в редактор, выберите «Диспетчер игр» в иерархии и перетащите сборный куб с панели проекта в переменную «Куб» в Инспекторе. Заполните значения для вашего нереста здесь тоже. Вы можете поиграть с ним, чтобы сделать его настолько сложным или легким, насколько вам нравится. Обратите внимание, что стоит, чтобы ваши самые маленькие кубики появлялись достаточно высоко, чтобы Uniduino мог инициализироваться - проигрыш в игре до того, как вы сможете двигаться, может разочаровать!

Игровой менеджер

Готовый проект

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

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

С Arduino и Unity вы можете создать собственный контроллер практически из чего угодно. Вы создали Hi-Fi, который управляет космическим кораблем? Тостер, управляющий игровой платформой?

Если вы сделали такой проект, я бы очень хотел его увидеть! Отправьте это в комментариях ниже!

Ссылка на основную публикацию
Adblock
detector