Har du någonsin velat designa din egen spelkontroll? Det är lättare än du tror!
I det här korta projektet kommer vi att bygga en enkel anpassad spelkontroll att använda med Unity-spelmotorn. Den här kontrollern kommer att drivas av en Arduino Uno, även om du kan använda ett av de många alternativen som finns för detta projekt också. Vi kommer också att skapa ett grundläggande spel där du kommer att använda din handkontroll för att undvika fallande föremål och sakta ner tiden.
För detta projekt behöver du
Arduino eller liknande mikrokontroller 1 x 10k Ohm motstånd 1 x Momentan switch 1 x Potentiometer Hook-up ledningar En breadboard Unity spelmotor Uniduino plugin från Unity Asset Store ($30) Komplett projektkod, ifall du inte vill skriva ut den (Inkluderar inte Uniduino-plugin)
De flesta av dessa saker finns i ett Arduino startpaket. Om du inte har ett startkit kolla in vår guide för att välja det bästa för dig.
Du kan göra din kontroller så komplicerad som du vill, men för det här exemplet kommer vi att ställa in en potentiometer och en knapp – perfekt för att styra ett enkelt arkadspel.
Montering av din styrenhet
Ställ in din breadboard och Arduino som visas i bilden nedan. Det här är vad vi kommer att använda som vår spelkontroll, även om du kan använda nästan exakt samma inställning som en gör-det-själv midi-kontroller också!
Förbereder din Arduino
När du har anslutit allt, anslut din Arduino via USB. I Arduino Software IDE gå till Verktyg > Styrelse och Verktyg > Port för att välja vilken mikrokontroller och port du använder. Arduino IDE levereras med skissen vi behöver, och du kan hitta den under Arkiv > Exempel > Firmata > StandardFirmata. Klicka på Ladda upp så är du redo att börja.
Om du är ny på Arduino och ditt huvud smälter något, kolla in vår nybörjarguide för att hjälpa dig att få det att prata bra med din dator.
Konfigurera ditt Unity-projekt
I Unity, öppna Fönster > Asset Store för att komma åt Unitys Asset Store från Unity Editor. Sök i Asset Store efter Uniduino-plugin. Detta plugin låter dig ta emot och skicka data till och från dina Arduino-stift inuti Unity. Pluginen kostar i skrivande stund $30. Det är möjligt att göra det här projektet utan att köpa plugin, även om det är ganska komplicerat och du kan tycka att pluginet är mer praktiskt överallt.
Den här videon från skaparna av pluginet tar dig genom processen att testa att allt fungerar, tillsammans med förstagångsinstallationen. Observera att du kanske också måste återställa Unity-redigeraren på Windows.
Vi kan använda samma testpanel för att testa vår kontroller. Ställ in stift D2 på INPUT och Digital. Längre ner, ställ in stift A5 på ANALOG. Din potentiometer och knapp bör nu visa värden på skärmen bredvid deras pin-nummer. Framsteg!
Nu ska vi göra något vi kan kontrollera
Så vi har en kontrollant, men vad ska vi kontrollera? Nåväl, möjligheterna är oändliga, men för idag ska vi skapa ett väldigt enkelt dodging-spel för att testa vårt nya kontrollsystem. Vi kommer att gå över spelupplägget ganska snabbt, så om du är helt ny på Unity-motorn kan du hitta vår Unity-spelprogrammeringsguide för nybörjare för att få koll.
Vi kommer att bygga ett mycket grundläggande spel där ditt mål är att undvika din sfär till vänster och höger för att undvika fallande kuber, vilket kommer att använda din nytillverkade anpassade kontroller.
Skapa en ny scen och dra Uniduino prefab från Tillgångar > Uniduino > Prefabs in i din hierarki och dra Uniduino prefab till hierarkin. Vi behöver den där för att prata mellan vårt spel och vår handkontroll.
Klicka i Unity-hierarkin Skapa > Sfär och använd fliken Transform i Inspector för att flytta den till botten av spelskärmen.
Det är dags att skaffa kodning
Nu för att lägga till lite kod till denna fest. Med sfären vald i hierarkin klickar du Lägg till komponent > Nytt skript längst ner i inspektörsfönstret. Namnge det sphereMover och välj Ciss från rullgardinsmenyn. Klick Skapa och lägg till och skriptet kommer att läggas till i GameObject. Dubbelklicka på det för att öppna skriptet och ange denna kod:
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);
}
}
Ta en stund att läsa igenom kodkommentarerna. Hittills har vi deklarerat några variabler för vår Arduino, dess stift och vår Sphere. Vi har också använt
Start- och ConfigurePins-metoder för att initiera vår Arduino på körtid. Låt oss spara vårt manus och gå tillbaka till Unity-redigeraren och se vad som har ändrats.
Vi kan nu se våra publika variabler i inspektörsfönstret. Låt oss se vad vi kan ange i detta skede för att hjälpa oss senare. Vi vet vilka pins vi använder på Arduino från vår konstruktion tidigare, vi kan ange dem. Vi vet också från vårt experiment tidigare hur långt vi vill att vår sfär ska kunna färdas åt vänster och höger så att den inte ramlar av skärmen. Låt oss ange dessa värden nu.
De första tecknen på liv
Det är dags att faktiskt se värden från vår Arduino inuti Unity Editor. För närvarande kan vi lägga till en rad kod till vårt sphereMover-skripts uppdateringsfunktion och spara skriptet igen.
void Update ()
{
//We assign the value the arduino is reading from our potentionmeter to our potValue variable
potValue = arduino.analogRead(potPinNumber);
}
Nu när vi har vår potValue-variabel uppdaterad varje bildruta, kan vi se dess värde i realtid i Unity Inspector. Innan vi testar det vore det ett bra tillfälle att kontrollera att Uniduino-kontakten lyssnar på rätt port. Klicka på Uniduino i Heirarchy och kontrollera dess portnamn i Inspector. Om det är tomt, fyll i rätt portnummer för din Arduino. I det här fallet var det COM4, även om det kan vara annorlunda för dig. Kontrollera att du använder Arduino IDE om du är osäker.
Välj din sfär i hierarkin och klicka på knappen Spela högst upp på skärmen. Systemet behöver några sekunder för att initiera, varefter du bör börja se Pot Value-variabeln ändras i inspektören när du flyttar potentiometern.
Nu snackar vi! Nåväl, strängt taget talar Unity och Arduino, men vem räknas? Om du har kommit så långt och inte ser värdeförändringen i inspektören, kontrollera installationsstegen och se till att du har valt rätt port för din Arduino.
Låt oss flytta denna sfär
Nu när vi har en potValue-variabel som uppdateras, vill vi använda detta värde för att flytta vår sfär. När potentiometern är hela vägen till vänster vill vi att sfären ska vara på skärmens vänstra sida och vice versa. Objekt i Unity är placerade vid en punkt i vektorrymden, som bestäms av värdena för dess Transform.position. I bilden nedan, där sfären är längst bort till vänster som vi skulle vilja ha den, kan du se att dess positionsvektor är 9,5, -4, 0.
Vi vill påverka sfärens X-position. Tyvärr kommer det inte att fungera att använda värdena från vår potentiometer direkt, eftersom när potentiometern är hela vägen till vänster ger den ett värde på 0 — vilket skulle placera vår sfär mitt på skärmen. I den andra ytterligheten skulle potentiometerns högsta värde, 1023, placera kuben långt borta till höger om vår skärm. Ej användbar. Vad vi behöver här är lite matematik.
Varför göra matematik när Unity kommer att göra det åt dig?
För de av er där ute som är rädda för att stirra på ett papper som är täckt av orimliga siffror (även om det finns några bra webbplatser som kan hjälpa dig att lära dig matematik), var inte rädd. Vi behöver ett sätt att få våra potentiometervärden att överensstämma med vår sfärs X-position. Lyckligtvis kan vi använda en Förlängningsmetod.
En förlängningsmetod är ett skript som gör ett specifikt jobb åt oss. I det här fallet ger vi den de värden vi har, och den returnerar dem mappade till varandra, redo att användas i vår sphereMover manus. Klicka på högst upp i projektpanelen Skapa > C#-skript och döp det till ExtensionMethods. Ange koden nedan i skriptet:
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;
}
}
Spara skriptet och gå tillbaka till ditt sphereMover-skript. Vi kan nu använda den här Remap-funktionen i vårt ExtensionMethods-skript i vår uppdateringsfunktion för att konvertera våra potentiometervärden till användbara värden i vårt spel. Under där vi just tilldelade variabeln potValue, skriv följande:
Prompten visar oss att vår Remap tar två uppsättningar av Från- och Till-värden och mappar dem tillsammans. Vi kan lägga in våra värderingar i detta.
mappedPot = potValue.Remap(0, 1023, leftEdge, rightEdge);
Spara ditt manus, gå tillbaka till Unity-redigeraren och tryck på play-knappen. Du bör nu se att den Mappade Pot-variabeln ändras när du flyttar potentiometern för att motsvara de värden vi bestämt för våra Vänster- och Högerkanter. Luta dig tillbaka och tacka ditt ExtensionMethods-skript. Inte en miniräknare i sikte.
Notera: om du märker att dina värden är omvända, så när din potentiometer är hela vägen till höger får du ett negativt värde för din Mappad Pot-variabel, kan du ha din potentiometer inställd på fel sätt. Lyckligtvis kan du fixa detta utan att göra någon omkoppling. Du kan helt enkelt byta värden när du mappar om dem:
Nu har vi äntligen användbara värden. Nu är allt som återstår att göra att tilldela dessa värden till vår sfärs X-position:
//Assign the mapped pot value to the sphere's x position
transform.position = new Vector3(mappedPot, transform.position.y, transform.position.z);
Spara ditt manus, gå tillbaka till Unity-redigeraren och tryck på play. Du bör nu kunna flytta din Sphere till vänster och höger med hjälp av din potentiometer!
Att sätta knappen i arbete
Nu när vi har vår sfär i rörelse, skulle det inte vara skönt att ha ett sätt att sakta ner saker och ting lite när vi hamnar i en trång plats? Vi kommer att använda vår knapp för att sakta ner tiden i vårt spel. Öppna ditt sphereMover-skript och lägg till den här koden i din uppdateringsfunktion
//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;
Nu har vi mekaniken i vårt spel, låt oss lägga till några hinder! Vi kommer att använda sfärens naturliga fiende, kuben. Klicka i hierarkin Skapa > 3d-objekt > Kub. I kubens inspektör, Lägg till komponent > Fysik > Rigidbody. Ställ in Drag-värdet för rigidbody till 5. Under Box Collider-komponenten i inspektören väljer du också Is Trigger. Detta gör att vi kan upptäcka kollisioner med vår sfär.
Skapa ett skript på kuben och kalla det collideWithSphere, öppna skriptet och ta bort start- och uppdateringsfunktionerna eftersom vi inte kommer att behöva dem den här gången. Ange denna kod:
using UnityEngine;
using System.Collections;
public class collideWithSphere : MonoBehaviour
{
void OnTriggerEnter(Collider other)
{
Destroy(other.gameObject);
}
}
OnTriggerEnter skickar ett meddelande när triggerkollideraren träffar en annan kolliderare. I det här fallet säger vi åt den att förstöra vad den än rör. Spara skriptet och gå tillbaka till Unity-redigeraren. Dra kuben från hierarkin till projektpanelen. Du kommer att märka att texten i kuben i hierarkin har blivit blå. Det beror på att vi har skapat en prefab och sparat den i vårt projekt. Ta bort din kub från hierarkin nu.
Allt vi behöver nu är ett skript för att skapa kuberna. Klicka i hierarkin Skapa > Skapa tom, och byt namn på den till Game Manager i Inspector och lägg till ett skript som heter gameManager. Öppna skriptet och lägg till denna kod:
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 ()
{}
}
Spara skriptet. Tillbaka i redigeraren, välj Game Manager i hierarkin och dra din kubprefab från projektpanelen till Cube-variabeln i Inspector. Fyll i värdena för din lek här också. Du kan pilla med den för att göra den så svår eller lätt som du vill. Observera att det är värt att låta dina lägsta kuber skapas tillräckligt högt för att tillåta Uniduino att initiera — att förlora spelet innan du kan flytta kan vara frustrerande!
Det färdiga projektet
Nu när du trycker på play kommer kuberna att spawna ovanför dig och falla. Du kan använda din potentiometer för att undvika dem, och din knapp för att sakta ner tiden.
I det här projektet har vi skapat en anpassad kontroller med en Arduino, konfigurerat Unity och Uniduino för att kommunicera med den, och skapat ett enkelt spel för att testa det. Koncepten här kan appliceras på nästan alla projekt, och det finns till och med game jams som är specialiserade på anpassade kontroller.
Med Arduino och Unity kan du skapa en anpassad kontroller från nästan vad som helst. Har du skapat en hi-fi som styr en rymdfarkost? En brödrost som styr ett plattformsspel?
Om du har gjort ett sådant här projekt skulle jag gärna se det! Lägg upp det i kommentarerna nedan!
Om författaren
Ian Buckley (220 artiklar publicerade)
Ian Buckley är en frilansjournalist, musiker, artist och videoproducent bosatt i Berlin, Tyskland. När han inte skriver eller står på scen, pysslar han med DIY-elektronik eller kod i hopp om att bli en galen vetenskapsman.
Mer från Ian Buckley
Prenumerera på vårt nyhetsbrev
Gå med i vårt nyhetsbrev för tekniska tips, recensioner, free e-böcker och exklusiva erbjudanden!
Klicka här för att prenumerera
