0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

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

454398 来源:网络整理 作者:网络整理 2019-11-28 11:43 次阅读

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

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

对于此项目,您将需要

Arduino或类似的微控制器

1 x 10k欧姆电阻

1 x瞬时开关

1 x电位计

连接线

面包板

Unity游戏引擎

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

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

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

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

组装控制器

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

准备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游戏编程初学者指南》很有用。

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

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

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

现在该开始编码了。

现在要向此聚会添加一些代码。在“层次结构”中选择球体后,点击其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编辑器,看看有什么更改。

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

最初的生命迹象

是时候在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。

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

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

让我们移动这个球体

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

我们想影响球体的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变量的位置,键入以下内容:

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

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

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

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

现在,我们终于有了可用的值。现在剩下要做的就是将这些值分配给我们球体的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初始化是值得的-在移动之前输掉游戏可能会令人沮丧!

完成的项目

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

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

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

责任编辑:wv

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

    关注

    112

    文章

    16317

    浏览量

    177792
  • Arduino
    +关注

    关注

    188

    文章

    6468

    浏览量

    186935
  • Unity
    +关注

    关注

    1

    文章

    127

    浏览量

    21803
收藏 人收藏

    评论

    相关推荐

    开放式激光振镜运动控制器在Ubuntu+Qt下自定义图形标刻

    开放式激光振镜运动控制器在Ubuntu+Qt下自定义图形标刻
    的头像 发表于 10-08 10:45 632次阅读
    开放式激光振镜运动<b class='flag-5'>控制器</b>在Ubuntu+Qt下<b class='flag-5'>自定义</b>图形标刻

    如何将自定义逻辑从FPGA/CPLD迁移到C2000™微控制器

    电子发烧友网站提供《如何将自定义逻辑从FPGA/CPLD迁移到C2000™微控制器.pdf》资料免费下载
    发表于 09-23 12:36 0次下载
    如何将<b class='flag-5'>自定义</b>逻辑从FPGA/CPLD迁移到C2000™微<b class='flag-5'>控制器</b>

    创建自定义的基于闪存的引导加载程序(BSL)

    电子发烧友网站提供《创建自定义的基于闪存的引导加载程序(BSL).pdf》资料免费下载
    发表于 09-19 10:50 0次下载
    创建<b class='flag-5'>自定义</b>的基于闪存的引导加载程序(BSL)

    如何自定义内存控制器的设置

    在FreeRTOS中自定义内存控制器的设置,主要涉及到内存分配策略的选择和配置。FreeRTOS提供了多种内存分配策略,如heap_1、heap_2、heap_3、heap_4和heap_5,每种
    的头像 发表于 09-02 14:28 455次阅读

    EtherCAT运动控制器PT/PVT实现用户自定义轨迹规划

    EtherCAT运动控制器PT/PVT实现用户自定义轨迹规划。
    的头像 发表于 08-15 11:49 612次阅读
    EtherCAT运动<b class='flag-5'>控制器</b>PT/PVT实现用户<b class='flag-5'>自定义</b>轨迹规划

    NVIDIA NeMo加速并简化自定义模型开发

    如果企业希望充分发挥出 AI 的力量,就需要根据其行业需求量身定制的自定义模型。
    的头像 发表于 07-26 11:17 740次阅读
    NVIDIA NeMo加速并简化<b class='flag-5'>自定义</b>模型开发

    Chrome移动版支持自定义菜单栏功能

    在先前版本中,用户通过点击浏览右上角的三个点按钮即可调出包含各类图标与操作的菜单。而此次更新后,Chrome新增了“自定义菜单”选项,允许用户自主控制该区域的展示内容。
    的头像 发表于 05-27 15:00 790次阅读

    HarmonyOS开发案例:【 自定义弹窗】

    基于ArkTS的声明式开发范式实现了三种不同的弹窗,第一种直接使用公共组件,后两种使用CustomDialogController实现自定义弹窗
    的头像 发表于 05-16 18:18 1351次阅读
    HarmonyOS开发案例:【 <b class='flag-5'>自定义</b>弹窗】

    TSMaster 自定义 LIN 调度表编程指导

    LIN(LocalInterconnectNetwork)协议调度表是用于LIN总线通信中的消息调度的一种机制,我们收到越来越多来自不同用户希望能够通过接口实现自定义LIN调度表的需求。所以在
    的头像 发表于 05-11 08:21 652次阅读
    TSMaster <b class='flag-5'>自定义</b> LIN 调度表编程指导

    HarmonyOS开发案例:【UIAbility和自定义组件生命周期】

    本文档主要描述了应用运行过程中UIAbility和自定义组件的生命周期。对于UIAbility,描述了Create、Foreground、Background、Destroy四种生命周期。对于页面
    的头像 发表于 05-10 15:31 1237次阅读
    HarmonyOS开发案例:【UIAbility和<b class='flag-5'>自定义</b>组件生命周期】

    HarmonyOS开发实例:【自定义Emitter】

    使用[Emitter]实现事件的订阅和发布,使用[自定义弹窗]设置广告信息。
    的头像 发表于 04-14 11:37 993次阅读
    HarmonyOS开发实例:【<b class='flag-5'>自定义</b>Emitter】

    鸿蒙ArkUI实例:【自定义组件】

    组件是 OpenHarmony 页面最小显示单元,一个页面可由多个组件组合而成,也可只由一个组件组合而成,这些组件可以是ArkUI开发框架自带系统组件,比如 `Text` 、 `Button` 等,也可以是自定义组件,本节笔者简单介绍一下自定义组件的语法规范。
    的头像 发表于 04-08 10:17 621次阅读

    自定义PSoC6微控制器板上建立BLE连接,BLE启动不起作用的原因?

    我正在尝试在自定义 PSoC 6 微控制器板上建立 BLE 连接。 我正在使用一个适用于我的开发板的 BLE 示例项目。 布局包括两个用于 BLE 的 ECO 和 WCO 晶体振荡。 该程序一直
    发表于 02-01 07:10

    基于YOLOv8实现自定义姿态评估模型训练

    Hello大家好,今天给大家分享一下如何基于YOLOv8姿态评估模型,实现在自定义数据集上,完成自定义姿态评估模型的训练与推理。
    的头像 发表于 12-25 11:29 2833次阅读
    基于YOLOv8实现<b class='flag-5'>自定义</b>姿态评估模型训练

    博途用户自定义库的使用

    博途官方提供了很多库,比如:基本函数库、通信库、安全库、驱动库等等,用户可以使用库中的函数/函数块来完成具体的控制任务。除了官方的库,我们也可以创建自己的库(用户自定义库)。比如,把项目
    的头像 发表于 12-25 10:08 909次阅读
    博途用户<b class='flag-5'>自定义</b>库的使用