电子说
您曾经想设计自己的游戏控制器吗?
在这个简短的项目中,我们将构建一个简单的自定义游戏控制器,以与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
全部0条评论
快来发表一下你的评论吧 !