书接上回,完成了后视镜头中点击收集垃圾的操作。但是,在Unity编辑器中无法测试真正的效果。因为用鼠标点击和触碰屏幕Touch是两个不同的input类型。同样的,VR/AR环境中的某些input也无法直接在编辑器中测试,或者说会有不同的测试效果。因此,需要通过相应的外置工具来完成更加真实的测试。对于手机端的测试,Unity Remote是最直接简单、方便操作的工具之一。
❗️本期内容有许多复杂的部分,强烈建议配合视频食用,效果更佳哦~
从零开始的Unity太空清理游戏|Part 5
在手机上测试你的游戏 – Unity Remote
(Unity Remote手册)
Unity Remote是支持Andriod、iOS、tvOS操作系统,连接手机端和Unity编辑器的测试工具。它可以接收到移动端的输入数据,比如触碰屏幕、GPS等。以此在不需要完整build的情况下,完成手机端用户测试。除了略微下降的画面帧率,Unity Remote能够完全模拟移动端的使用情况,我们在上一章节中完成的内容在这里可以体现出来了。
注意:Unity Remote不支持跨系统的测试,Win系统和macOS的Unity也有很多不兼容之处。
-
首先在手机上安装Unity Remote,在app store/商店中可以免费下载。
(App Store截屏)
-
用数据线将手机和电脑连接。可能需要在手机上选择”相信此设备“。
-
打开Unity项目。在Edit>>> Project Settings >>> Editor 的Device中下拉选择你的移动设备。
-
设置完成后,打开手机上的Unity Remote,再点击Editor中的“Play”按钮,手机端和编辑器中就会同步开始运行了。
将手机从竖屏转换到横屏,这样画面才不会被拉伸。
你可能会发现在手机上运行时,用户界面中的摇杆和按钮位置不太对劲。这是因为手机的屏幕像素一般会大很多,而摇杆和按钮并没有相应的扩大。要完成这一点,只需要将canvas的UI Scale Mode从“Constant Pixel Size”换成“Scale With Screen Size“就好了。
(UI Scale Mode)
(Constant Pixel Size Vs. Scale With Screen Size)
在手机上切换到后视镜后,点击两种垃圾就可以让他们消失了。
防穿模 - Collider & Rigidbody
如果驾驶飞船冲向中间的行星,你会发现它直接穿过了星球。为了防止这样穿模的情况,我们需要给飞船加上Collider和RigidBody两个部分。
Collider是Unity中一个非常重要的API,可以探测物体之间的碰撞并引发任意的反应。而RigidBody的存在是为了实现某个物体在真实物理环境下的行为。比如在现实生活中,具有质量的物体A会受到重力作用,它不会漂浮在空中,而是会坠落。另一个例子是两个物体相撞的时候,质量较大的物体由于惯性更大,受作用力产生的位移会相对小。
-
点击Spacecraft,右侧最下方点击“Add Component”,输入Collider → Box Collider
-
完成后会看到物体周边出现了一个绿色的框,这就是飞船Collider的范围。任何同样具有Collider的物体进入或离开这个框,都被探测到。
-
-
同样的方法加上Rigidbody
-
Mass:可以调整物体的质量(决定它的惯性),这里可以保持不变
-
Use Gravity:是否受到重力,如果受到重力会在空中下落。由于这里是太空,我们取消选择这一项
-
Is Kinetic:是否受到物理作用等;如果勾选了,物体将不会受到任何力和碰撞的作用。同样取消选择这一项
-
加上这两个部分后,飞船就如我们所愿,不会穿过其他物体了。
在这个游戏中,飞船还可以通过接触到太空中的垃圾来收集它们。这项功能也需要Collider,它不仅能够模拟物体在真实物理世界的状态,也能监控有collider的物体之间是否发生碰撞,并且做出相对应的行为。
-
打开Spacecraft的script,添加
void OnCollisionEnter(Collision collision)
{
...
}
-
OnCollisionEnter会在游戏开始后的每一帧监听是否有带有Collider的物体与Spacecraft发生碰撞。如果有,在碰撞开始的那一帧,就会触发这个方法中的行为
-
在OnCollisionEnter()中输入如下:通过collision.gameObject获取与飞船发生碰撞的物体,如果这个物体的标签是”Moon Trash”和”Space Trash”之一,就将他们消除
// If collide with Moon trash
if (collision.gameObject.CompareTag("Moon Trash") || collision.gameObject.CompareTag("Space Trash"))
{
collision.gameObject.SetActive(false);
}
位置触发剧情 – OnTriggerEnter
在太空中,当飞船偏航,距离行星越来越远到一定距离时,会触发“距离过远”的警报。如果继续远离到达边界,则会触发自动返航。这类似于角色走到某个特定位置时触发剧情这种情况,其实这也是通过Collider完成的。
但与物体间的碰撞不同之处是,特定的位置不能有rigidbody,否则会阻挡玩家走入这个区域。对于一方(飞船)有rigidbody而另一方(位置)没有,之间的碰撞就需要用到trigger了。
首先在场景中区分各个区域,因为这是3D场景,可以用球形/立方体来囊括不同区域。我在这里选择用球体,保证各个方向到中心的位置一致。
-
建立两个大小不同的同心球体,命名为“InBound”和“OutBound”。
-
把它们的mesh删掉,场景中不可见
-
移动位置,确保它们的中心为行星。
-
-
分别加上”Sphere Collider”组件,新建并添加InBound和OutBound标签
-
勾选“is Trigger”
-
Trigger可以让我们得到一个物体与另一个物体碰撞的不同状态,分别有Enter、Stay和Exit。
游戏开始时,飞船是在两个球体当中的。当飞船越飞越远,退出inBound时,需要显示一个提示。如果飞船转向,重新进入inBound,就将提示关掉。
-
打开Spacecraft代码,加入新的公开变量warning,它一开始的状态应该为SetActive(false)
-
如果进入了InBound就关掉Warning,如果离开了InBound就打开Warning
void OnTriggerEnter(Collider other)
{
if (other.gameObject.CompareTag("InBound"))
{
warning.SetActive(false);
}
}
void OnTriggerExit(Collider other)
{
if (other.gameObject.CompareTag("InBound"))
{
warning.SetActive(true);
}
}
-
保存,回到编辑器
-
Canvas中新建一个panel,加TextMeshPro,修改文字为“Warning: Too far from cleaning Space. Please return.”
-
简单修改背景颜色等
-
-
将panel关闭,并拖拽到SpaceCraft中“warning”变量对应的空中。
同样的道理,在退出OutBound范围后,飞船需要自动返航(换句话说是旋转180度)。
-
在OnTriggerExit中加入
if (other.gameObject.CompareTag("OutBound"))
{
transform.Rotate(Vector3.up, 180);
}
- 保存,返回编辑器。现在就实现了自动调转方向返航。
Main Takeaway
Collider是Unity开发中十分重要、几乎不可或缺的一个API。如果想要进一步学习相关内容,Unity官方也给出了非常简单明了的Collider相关课程,通过实际例子在短短几分钟内将清了初级开发者需要的所有相关知识。
如果有任何疑问或者建议,也欢迎在下方留言评论哟~