怎样使用Arduino和Unity制作自定义游戏控制器

电子说

1.3w人已加入

描述

您曾经想设计自己的游戏控制器吗?

在这个简短的项目中,我们将构建一个简单的自定义游戏控制器,以与Unity游戏引擎一起使用。该控制器将由Arduino Uno供电,尽管您也可以使用该项目的众多替代产品之一。我们还将创建一个基本的游戏,在该游戏中,您将使用控制器来避免物体掉落和减慢时间。

对于此项目,您将需要

Arduino或类似的微控制器

1 x 10k欧姆电阻

1 x瞬时开关

1 x电位计

连接线

面包板

Unity游戏引擎

Unity Asset Store中的Uniduino插件(30美元)

完成项目代码,以防万一您不想编写它(不包括Uniduino插件)

这些东西大多数都可以在Arduino入门套件中找到。如果没有入门工具包,请查看我们的指南,为您选择最合适的指南。

您可以根据需要使控制器变得复杂,尽管在此示例中,我们将设置一个电位计和一个按钮–非常适合控制简单的街机游戏。

组装控制器

设置面包板和Arduino,如这是我们将用作游戏控制器的图像,尽管您也可以使用与DIY midi控制器几乎完全相同的设置!

Unity

准备Arduino

一旦一切都连接好,请通过USB连接Arduino。在Arduino Software IDE中,转到工具》板和工具》端口,以选择要使用的微控制器和端口。 Arduino IDE随附了我们所需的草图,您可以在文件》示例》固件》 StandardFirmata 下找到它。单击“上载”,您就可以准备就绪。

如果您是Arduino的新手,并且脑袋有点融化,请查看我们的初学者指南,以帮助您与计算机进行良好的交谈。

设置您的Unity项目

InUnity,打开 Window》 Asset Store 可以从Unity编辑器中访问Unity的Asset Store。在资产商店中搜索Uniduino插件。这个插件将允许您在Unity内部的Arduino引脚之间收发数据。在撰写本文时,该插件的价格为30美元。可以在不购买插件的情况下进行此项目,尽管它相当复杂,并且您可能会发现插件更方便。

此视频来自插件创建者的帮助,带您完成了所有功能的测试过程以及首次设置。请注意,您可能还必须在Windows上重置Unity编辑器。

我们可以使用同一测试面板来测试我们的控制器。将引脚D2设置为INPUT和Digital。再往下,将引脚A5设置为ANALOG。电位计和按钮现在应该在屏幕上的引脚号旁边显示值。进步!

Unity

现在可以做一些我们可以控制的事情了

所以我们有一个控制器,但是我们应该控制什么呢?好吧,可能性无穷无尽,但今天,我们将创建一个非常简单的躲避游戏,以测试我们的新控制系统。我们将很快地完成游戏设置,因此,如果您是Unity引擎的新手,您可能会发现《 Unity游戏编程初学者指南》很有用。

我们将构建一个非常基本的游戏,其中您的目标是向左和向右避开球体以避免掉落立方体,这将利用您新创建的自定义控制器。

创建一个新场景并将Uniduino预制件从资产》 Uniduino》中拖动预制件进入您的阶层,然后将Uniduino预制件拖入层次结构。

在Unity层次结构中,单击 Create》 Sphere ,然后使用检查器中的“变换”选项卡将其移至底部。游戏画面。

Unity

现在该开始编码了。

现在要向此聚会添加一些代码。在“层次结构”中选择球体后,点击其Inspector窗口底部的添加组件》新脚本。将其命名为 sphereMover ,然后从下拉菜单中选择 C 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,其引脚和Sphere声明了一些变量。我们还使用了

Start和ConfigurePins方法在运行时初始化Arduino。保存脚本,然后返回Unity编辑器,看看有什么更改。

Unity

我们现在可以在Inspector窗口中看到我们的公共变量。让我们看看我们在现阶段可以输入什么以帮助我们以后。我们早先知道我们在Arduino上使用的是什么引脚,我们可以输入它们。我们还从实验中更早地知道了我们希望球体能够左右移动的距离,以使其不会从屏幕上掉落。现在让我们输入这些值。

Unity

最初的生命迹象

是时候在Unity Editor中实际查看来自Arduino的值了。现在,我们可以在sphereMover脚本的Update函数中添加一行代码,然后再次保存该脚本。

void Update ()

{

//We assign the value the arduino is reading from our potentionmeter to our potValue variable

potValue = arduino.analogRead(potPinNumber);

}

现在,我们的potValue变量每帧都会更新一次。 ,我们可以在Unity Inspector中实时看到它的价值。在进行测试之前,现在是时候检查Uniduino插件是否在正确的端口上进行侦听。在层次结构中单击Uniduino,然后在检查器中检查它的端口名称。如果为空白,请为您的Arduino输入正确的端口号。在这种情况下,它是COM4,尽管它可能与您有所不同。如果不确定,请检查使用Arduino IDE。

Unity

在层次结构中选择球体,然后单击屏幕顶部的“播放”按钮。系统需要几秒钟的初始化时间,此后您应该在移动电位器时开始在检查器中看到Pot Value变量的变化。

Unity

现在我们正在交谈!好吧,严格来说,Unity和Arduino在说话,但是谁在数呢?如果您到此为止并且在检查器中看不到值的变化,请检查设置步骤,并确保为Arduino选择了正确的端口。

让我们移动这个球体

现在我们已经更新了potValue变量,我们想使用该值来移动我们的球体。当电位计完全移到左侧时,我们希望球体位于屏幕的左侧,反之亦然。 Unity中的对象位于Vector空间中的某个点,该点由其Transform.position的值确定。在下面的图像中,球体在我们想要的最左边的位置,您可以看到它的位置向量是9.5,-4,0。

Unity

我们想影响球体的X位置。不幸的是,直接使用电位器的值将不起作用,因为当电位器一直向左移动时,其值为0,这会使我们的球体位于屏幕中间。在另一个极端,电位器的最高值1023将使立方体远离屏幕的右侧。没用。我们需要的是一些数学。

为什么Unity会为您做数学?

对于那些在那里的人,他们害怕地盯着一张无意义数字覆盖的纸(尽管有一些很棒的网站可以帮助您学习数学),但不要害怕。我们需要一种使电位计值与球体的X位置相对应的方法。幸运的是,我们可以使用扩展方法。

扩展方法是为我们完成特定工作的脚本。在这种情况下,我们给它提供我们拥有的值,并返回它们之间的映射关系,以便在我们的 sphereMover 脚本中使用。在“项目”面板的顶部,单击创建》 C#脚本,并将其命名为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;

}

}

保存该脚本,然后回到您的sphereMover脚本。现在,我们可以在Update函数的ExtensionMethods脚本中使用此Remap函数,将电位计值转换为游戏中可用的值。在我们刚刚分配了potValue变量的位置,键入以下内容:

Unity

提示显示我们的Remap接受了两组From和To值,并映射了他们在一起。我们可以在其中输入值。

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

保存您的脚本,回到Unity编辑器,然后单击播放按钮。现在,您应该看到,移动电位计时,“映射的电位器”变量会发生变化,以与我们为左右边缘确定的值相对应。花一点时间坐下来,感谢您的ExtensionMethods脚本。

Unity

注意:如果您注意到自己的值是相反的,那么当电位计完全移到右边时如果您的“ Mapped Pot”变量获得负值,则可能是电位计设置错误。幸运的是,您无需进行任何重新布线即可解决此问题。重新映射它们时,只需切换值即可:

Unity

现在,我们终于有了可用的值。现在剩下要做的就是将这些值分配给我们球体的X位置:

//Assign the mapped pot value to the sphere’s x position

transform.position = new Vector3(mappedPot, transform.position.y, transform.position.z);

保存脚本,返回Unity编辑器并按播放。现在,您应该可以使用电位计将Sphere左右移动!

将按钮置于工作状态

现在我们可以移动球形了,不是吗?当我们在狭窄的地方时,有什么办法可以减慢速度吗?我们将使用按钮来减慢游戏时间。打开您的sphereMover脚本,然后将此代码添加到您的Update函数中

//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”组件下,选择“ Is Trigger”。

在多维数据集上创建一个脚本,并将其命名为 collideWithSphere ,打开脚本并删除Start和Update函数,这将使我们能够检测到与Sphere的碰撞。这次不需要他们。输入以下代码:

using UnityEngine;

using System.Collections;

public class collideWithSphere : MonoBehaviour

{

void OnTriggerEnter(Collider other)

{

Destroy(other.gameObject);

}

}

OnTriggerEnter每当触发对撞机碰到另一个对撞机时都会发送一条消息。在这种情况下,我们要告诉它销毁一切。保存脚本并返回到Unity编辑器。将多维数据集从层次结构拖动到“项目”面板。您会注意到层次结构中的多维数据集文本已变为蓝色。这是因为我们已经创建了一个预制件并将其保存在我们的项目中。现在从层次结构中删除多维数据集。

我们现在需要的是一个脚本,用于生成多维数据集。在层次结构中,单击创建》创建空白,然后将其重命名为“检查器”中的“游戏管理器”,然后向其中添加一个名为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初始化是值得的-在移动之前输掉游戏可能会令人沮丧!

Unity

完成的项目

现在,当您按Play时,多维数据集将在您上方生成并掉落。您可以使用电位计来避免它们,并可以使用按钮来减慢时间。

在此项目中,我们使用Arduino创建了自定义控制器,将Unity和Uniduino配置为与其通信,并创建了一个简单的控件。游戏进行测试。这里的概念几乎可以应用于任何项目,甚至还有专门针对自定义控制器的游戏卡纸。

借助Arduino和Unity,您几乎可以从任何东西创建自定义控制器。您是否创建了控制飞船的高保真音响?一个控制平台游戏的烤面包机?

责任编辑:wv

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分