「Unity入门」Step by step的太空清理垃圾游戏Part 4: 触碰收集垃圾

本文详细介绍了如何在Unity游戏中实现太空垃圾清理的后视镜模式,包括切换前后镜头、处理Touch输入、转换屏幕点击到Raycast、以及使用Tag区分垃圾与其他物体。读者将学习到如何通过Camera、Trigger、Screen和Tag进行交互设计。
摘要由CSDN通过智能技术生成

配合视频食用效果更好哦~

Step by step的太空垃圾清理游戏教程-Part 4

作为太空环境保护者,除了控制飞船移动外,我们还可以切换前视镜和后视镜。在前视镜状态下,驾驶员需要驾驶飞船碰撞垃圾来收集它;在后视镜的状态下,驾驶员只需要点击垃圾,垃圾就会自动被收集。在本节中,我们将用trigger,camera,screen和tag来完成这两个状态。

切换前后镜头 – enabled & SetActive

首先,让我们实现切换前后镜头的功能。我们已经有了一个主镜头“Main Camera”在飞船前侧作为主视角。接下来,需要另一个镜头放到飞船后侧。

  • GameObject - Camera 新建一个镜头。更改名为“Back Camera”

  • 将Back Camera移动到Spacecraft的下方,成为Spacecraft的子物体(child)

    • 开始运行后,Back Camera也会跟着Spacecraft一起移动了

  • 将镜头的位置移动到飞船的后侧,调整角度到合适的视角。

    • 单击镜头,在场景右下角能够看到镜头的视角

添加后视镜头后,我们来完成前后镜头的切换。我选择的交互方式是添加一个“前/后”的按钮,用来转换前后镜头。当然,也有其他同样合适的方式,其中逻辑都是类似的。

建一个按钮(Button):

  • 右击“Canvas” – UI – Button-TextMeshPro

    • TextMeshPro指的是按钮上的文字,可以用TextMeshPro而不仅仅是简单的Text。如果是第一次用到Button,在弹出的对话框中选择“import TMP Essentials”

    • Button的初始结构是Button - Text。在Button的“Image”中调整按钮的背景,Text中修改文字和字体...

  • 重命名为“Back Camera Button”。选择合适的背景颜色。将按钮的文字改成“Back Camera”。调整按钮的大小和位置。

  • 复制整个按钮,用作前镜头切换。只需要修改名称和文字为“Front Camera”。

    • 两个按钮是为了能够切换。

添加按钮后,我们可以用它来控制两个镜头的“开/关“。这里要用到一个常用的功能——SetActive。通过把后面的参数设置为True或False,它能够把某个GameObject设置为Active(开)或inactive(关)。

  • 新建一个Script,命名为“CameraManager”。

  • 新建两个公开的变量frontCam和backCam,用来代表两个镜头。

public Camera frontCam;

public Camera backCam;
  • 在Start中,用enabled来设置两个镜头的初始状态

frontCam.enabled = true;

backCam.enabled = false;
  • 新建两个公开的按钮变量frontButton和backButton

public Button frontButton;

public Button backButton;
  • 记得先在script的顶端导入UnityEngine.UI,这条指令使我们能够运用Button

using UnityEngine.UI;
  • 在Start中,用AddListener设置两个按钮在被按时的要执行的操作

backButton.onClick.AddListener(BackClick);

frontButton.onClick.AddListener(FrontClick);
  • AddListener是一个常用的监听方法。前面加上onClick,Listener会在按钮被按到的时候执行后面参数中的方法。因此AddListener在设定按钮时很常用。

  • 来定义BackClick和FrontClick两个方法。

void BackClick()

{

frontCam.enabled = false;

backCam.enabled = true;

backButton.gameObject.SetActive(false);

frontButton.gameObject.SetActive(true);

}



void FrontClick()

{

backCam.enabled = false;

frontCam.enabled = true;

frontButton.gameObject.SetActive(false);

backButton.gameObject.SetActive(true);

}
  • 在被点到后,它们要做的是:控制相应镜头的开关、关掉另一个镜头、关掉此按钮、打开另一个按钮

按钮逻辑图

  • 保存并回到编辑器,新建一个空的GameObject,命名为“Camera Manager”。

  • 将CameraSwitch拖拽到Camera Controller中。并将公开变量赋值。

获取和转换屏幕点击位置 – Touch & Raycast

后视镜状态中,如果玩家点击太空中的垃圾,垃圾将会消失(被收集)。Unity用Touch这种类型来代替触碰屏幕的动作。Touch有很多自带的属性方便运用,比如phase代表触碰的阶段,position代表屏幕上被触碰的像素点位置等。可以用Input.touchCount> 0这个条件来判断屏幕是否被触碰,如果触碰的个数touchCount大于0,就说明有触碰存在,就是时候进行下一步了。

前面提到,可以用touch.position获取被触碰的像素点位置,就能得到玩家想要点击的地方。但问题是,屏幕是一个2D的平面,但我们的游戏是3D的世界,将得到的(x,y)直接当成(x,y,z)使用显然行不通。所以,我们需要将2D位置转换成3D镜头中的Ray。Ray的本意是“射线”,有着方向和起点。它与touch.position的最大不同在于,前者是相对于镜头,而后者是相对于屏幕。最后,将射线转换为RaycastHit,指的是射线碰到的物体。注意,只有带有collider的物体才能够被射线触碰到。点开两种垃圾的prefab,它们都应该有collider。

position → Ray → RaycastHit

  • 双击打开spacecraft代码文件,

    • 在update中,首先判断是否在后视镜头的状态下。如果是,进行后续。如果不是,则不需要做任何事。

  • 创建公开的镜头变量backCam

  • 在update中,判断backCam是否为enabled的状态

if (backCam.enabled) // Only enable touch-collecting when back camera is active

{



}
  • 判断是否有点击存在。如果发生了点击,对于每个点击我们都需要执行相同的步骤:

if (Input.touchCount> 0)

{

    foreach (Touch touch in Input.touches)

    {
        ...


    }

}
  • 先获取touch的位置,用ScreenPointToRay转换为Ray。再将ray转换为RaycastHit。通过RaycastHit的属性得到点击到的gameObject

Ray ray = backCam.ScreenPointToRay(touch.position); // Convert ray to camera view pos

RaycastHit hit;



if (Physics.Raycast(ray, out hit))

{

    ...

}
  • 最后,我们用hit.transform.gameObject来获取点击到的物体,并使之消失

GameObject obj_hit = hit.transform.gameObject;

obj_hit.SetActive(false);
  • 保存代码,回到编辑器。别忘了拖拽给backCam赋值

分类好帮手 – Tag

现在,在后视镜中,被点击到的物体都会消失。但问题是,垃圾之外的物体,比如星球、人造卫星等任何有collider的物体,都会消失。因此,需要一个条件来判断碰到的物体是不是垃圾。Unity中,常用的分类物体方法是加“标签”tag。可以自己创造标签,比如Moon Trash,Space Trash。多个物体可以用同一个标签。Unity还贴心的准备了很多好用的方法,比如FindWithTag,CompareTag等,非常方便。

给场景中的垃圾加上标签。

  • 在Inspector中,选择tag的下拉键,点击“Add tag…“

(给物体加上标签

创建新标签

  • 在新窗口中点击加号,输入标签的名称。分别创建”Moon Trash“和”Space Trash“两个标签。

  • 点击每一个垃圾物体,下拉tag,刚刚创建的标签中选择相应的。

加上标签后,还需要在script中加入判断标签的条件。

  • 双击打开spacecraft代码文件,在obj_hit.SetActive(false);之前加上判断条件

if (obj_hit.CompareTag("Moon Trash"))

{

    obj_hit.SetActive(false);

}



if (obj_hit.CompareTag("Space Trash"))

{

    obj_hit.SetActive(false);

}
  • 保存

注意,CompareTag后的标签内容一定要和创建的 一 模 一 样!不然的话,CompareTag会返回false值,也就无法进行后面的步骤了

在Unity中运行时,你可能会发现点击垃圾没有反应。这不是你的错,只是鼠标的点击无法被算作“Touch”。也就是说,只有在手机上测试才会有效果。后面的章节会介绍在手机上测试的简便方法。

如果有任何疑问或者建议,也欢迎在下方留言评论哟~

  • 18
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值