Unity开启篇(五) —— 一款简单射击游戏示例 (三)

版本记录

版本号 时间
V1.0 2018.12.17 星期一

前言

Unity是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。Unity类似于Director,Blender game engine, Virtools 或 Torque Game Builder等利用交互的图型化开发环境为首要方式的软件。其编辑器运行在Windows 和Mac OS X下,可发布游戏至WindowsMacWiiiPhoneWebGL(需要HTML5)、Windows phone 8和Android平台。也可以利用Unity web player插件发布网页游戏,支持Mac和Windows的网页浏览。它的网页播放器也被Mac 所支持。网页游戏 坦克英雄和手机游戏王者荣耀都是基于它的开发。
下面我们就一起开启Unity之旅。感兴趣的看下面几篇文章。
1. Unity开启篇(一) —— Unity界面及创建第一个简单的游戏 (一)
2. Unity开启篇(二) —— Unity界面及创建第一个简单的游戏 (二)
3. Unity开启篇(三) —— 一款简单射击游戏示例 (一)
4. Unity开启篇(四) —— 一款简单射击游戏示例 (二)

开始

首先看一下本文的写作环境

C# 7.2, Unity 2018.1, Unity

欢迎来到Unity迷你系列的第三部分也是最后一部分!在本教程中,您将学习Unity中的所有组件(Components),同时让您的英雄自由用子弹设计物体!

在这一点上,你已经完成了让所有主要角色都做好准备的目标,但它本质上是一个空洞的舞台。

在本教程中,您将通过使用组件(Components)为游戏添加一些交互性,这些组件是Unity游戏开发的基础。如果您将GameObject视为名词,那么组件将是动词或执行动作的部分;组件代表GameObject执行某些操作。

你已经学会了一些关于组件的知识。在本系列教程的前两部分中,您了解了每个GameObject如何具有一个必需组件:Transform组件,它存储GameObject的位置,旋转和缩放。

但Unity提供的组件远不止于此。 例如,有一个light组件可以照亮它附近的任何东西。 有一个会产生声音的audio source组件。 甚至还有一个particle system组件会产生一些令人印象深刻的视觉效果。 当然,如果没有一个组件能够满足您的需求,您可以编写自己的组件。

在本教程中,您将了解几种类型的组件,包括Rigidbody组件,script组件等。 在本教程结束时,您的海军陆战队员将会开始行动并开枪!

如果您完成了上一个教程,请打开当前的Bobblehead Wars项目,以便从中断的地方继续学习。

目前,海军陆战队员只知道如何像雕像一样站立。 如果他要避免成为外星人的零食,他需要四处走动。

你要添加的第一件事是一个Rigidbody组件,它将GameObject选入物理引擎。 通过添加它,您将启用GameObject与其他GameObjects的碰撞。


Adding the Rigidbody Component - 添加Rigidbody组件

Hierarchy中,选择SpaceMarine GameObject,然后单击Inspector中的Add Component按钮。

你会看到许多不同的类别。 当您知道所需的组件时,只需按名称搜索即可。 否则,请选择其中一个类别并选择最佳选项。

单击Physics类别,然后选择Rigidbody

你会看到一个Rigidbody组件被附加到GameObject上。恭喜! 您添加了第一个组件。

每个组件都有自己的一组属性,值等。 可以在Inspector或代码中更改这些属性。 组件也有自己的图标,以便于一目了然地确定其类型。

您会注意到每个组件右上角的一些图标,如下所示:

第一个图标是Reference图标。 点击它。 它将打开另一个窗口,其中包含该组件的文档页面。 如果您安装了文档,则此页面位于您的计算机上 - 是的,搜索栏可以正常工作。

第二个图标是Unity 2018中的新功能。这是预设presets按钮。 在自定义组件时,您可能更喜欢先前创建的某个预设配置。

Rigidbody组件中,选中IsKinematic复选框。 此外,取消选中Use Gravity选项。 您马上就会了解这些选项。 但是,一旦取消选中它们,请单击presets按钮。

您可以将该配置保存为预设,然后根据需要切换到该预设。 您还可以使用指定的预设创建新的GameObject,从而节省您的时间。

此对话框将列出所有预设。 单击Save current to and from the Project Browser,然后选择Presets文件夹。 称之为运动学(Kinematic)。 现在当您再次单击预设按钮时,您将看到新保存的预设。 当您想要进行更改时,预设是保存当前配置设置的好方法。

组件右上角的三个按钮中的最后一个是齿轮图标。 点击它。 此对话框将出现:

以下是此处列出的最重要选项:

  • Reset会将组件重置为其默认值。
  • Move to Front 和 Move to Back调整2D游戏中精灵的顺序。
  • Remove Component将从GameObject中删除组件 - 您可以撤消此操作。
  • Copy Component允许您从一个GameObject复制组件并将其粘贴到另一个GameObject上。
  • Paste Component as New会将复制的组件粘贴到GameObject。
  • Paste Component Values允许您从复制的组件覆盖当前组件的值。具体来说,您可以在游戏进行时复制组件的值。停止游戏后,您可以将这些值粘贴到另一个组件上。这非常有用,因为有时候在玩游戏时调整一些东西是很有用的。

从菜单中,选择remove component。现在再次单击add component按钮,然后将Rigidbody组件添加回GameObject。请记住,它属于Physics类别。最后,单击presets按钮并选择Kinematic预设。

请注意,Rigidbody组件是根据您的预设自动神奇更新的。但你可能会问,什么是Rigidbody

通过将Rigidbody组件添加到陆战队员中,您已经做到了这一点,以便他现在可以响应碰撞事件并响应重力。但是,你不希望他从敌人或墙壁上弹跳。你肯定想知道那些碰撞事件,但是你不希望英雄因为碰到一个列而失控。

isKinematic属性告诉物理引擎你手动控制陆战队员,而不是让物理引擎为你移动陆战队员。但物理引擎仍然知道陆战队员的位置以及它何时与某些东西发生碰撞。这是有帮助的,这样当陆战队员与外星人碰撞时,物理引擎会通知你,这样你就可以发生一些事情 - 比如陆战队员变得更加紧张!

通过取消选中Use Gravity选项,陆战队员不会受到重力的影响。再次 - 您不需要这个,因为您将手动移动陆战队员并且仅使用Rigidbody进行碰撞检测。

现在来到有趣的部分:是时候制作陆战队员舞了!或者移动。那也没关系。

Unity提供了一些内置组件,使移动变得简单。但出于学习目的,在本教程中。你将通过脚本的力量手动完成所有事情。


Introducing Scripting - 引入脚本

对于非程序员来说,脚本编写充其量只是一个很小的障碍。

来自艺术背景,我可以说脚本并不像你想象的那么难。 像任何事情一样,只需要一些时间和耐心来理解它是如何工作的。

在本教程中,您将使用C#编写脚本,C#是Microsoft开发的一种流行语言,适用于移动和桌面应用程序。 它功能丰富,功能齐全。 不幸的是,我无法在本教程中教授所有内容。

它专为非程序员设计,并在Unity环境中进行教学。

如果你是编程的初学者,一定要先检查一下。如果您是一位经验丰富的开发人员,或者是一位特别勇敢的初学者,请随时继续,因为本教程中的所有内容都是一步一步的;只要明白,没有C#知识,你的理解可能会有一些差距。

1. Why Not JavaScript? - 为什么不是JavaScript?

在当天,Unity发布了Javascript和一个名为Boopython变种。大多数开发人员在2017年使用C#,因此Javascript的支持被删除了。几年前Boo被弃用了。现在,所有脚本都完全用C#完成。

您可能会遇到引用Javascript的教程,但您甚至无法在编辑器中创建Javascript文件。这是一件好事,因为Unity已经专注于他们的C#实现,将其更新为近乎现代的语言版本。

C#可能需要一些时间来学习,但您可以利用Unity以外的编程技能。例如,如果您发现自己不喜欢游戏开发(或者很难谋生)而是喜欢这种语言,那么您可以将这些技能转换为C#开发工作,创建桌面或移动应用程序,甚至开发后端服务器应用程序。

编码在Unity中的工作方式是您创建scriptsscripts只是您附加到GameObjects的另一种类型的组件,您可以编写代码。

脚本派生自一个名为MonoBehaviour的类,您可以覆盖多个方法以获取特定事件的通知:

  • Update():此事件发生在每一帧。如果你的游戏以每秒60帧的速度运行,则Update()被调用60次。毋庸置疑,您不希望在此方法中进行任何繁重的处理。
  • OnEnable():当启用GameObject时以及非活动GameObject突然重新激活时调用。通常,当您暂时不需要它们但稍后需要时,您将停用GameObjects。
  • Start():在脚本的生命周期和调用Update()之前调用一次。这是进行设置和初始化的好地方。
  • Destroy():在对象进入GameObject之前调用它。这是一个清理的好地方,例如关闭网络连接。

您将在本教程中发现许多其他事件。要查看完整列表,请访问Unity网站上的MonoBehavior参考:


Creating Your First Script - 创建你的第一个脚本

好戏开场了!

您可以使用许多选项来创建脚本。 您可以单击Add Component按钮,然后选择New Script

但我希望您这样尝试:在项目浏览器中选择Scripts文件夹,然后单击Create按钮。 从下拉菜单中选择C#Script并将其命名为PlayerController

您将在Scripts文件夹中看到新脚本。 将它从Scripts文件夹拖到SpaceMarine GameObject上。

您现在应该看到脚本列为层次结构中SpaceMarine GameObject的组件之一。

您已添加了第一个自定义组件! 当然,它没有做任何事情......

在你做之前,你会在短时间内改变它,你需要了解Input Manager


Managing Input - 管理输入

输入是游戏的控件,如果您正在为台式计算机开发游戏,您的用户将期望能够重新绑定键。 Unity的Input Manager使这很简单,是游戏处理用户输入的首选方式。

要访问Input Manager,请单击Edit\Project Settings\Input

Inspector看起来很空。 单击单词Axes旁边的显示三角形。

展开后,您将看到可供您使用的所有预配置输入。

第一个属性是Size,它是您的游戏使用的输入数量。 您可以减少数量,并在需要更多输入时增加数量。 目前的投入量足以满足这个游戏的需求。

单击Horizontal旁边的显示三角形。 在这里,您可以配置水平轴的输入,即左或右。

下面进行详细说明:

  • Name是Unity提供输入的名称。此示例称为“Horizontal”,但您可以将其称为任何名字。这也是您在代码中引用的名称,稍后您将看到。
  • Descriptive Name and Negative Name是Unity游戏启动器中的用户想要重新映射密钥的名称。如果您愿意,可以禁用Unity游戏启动并提供您自己的键映射界面,因此这些不是必需属性。+ * NegativePositive Buttons是正在使用的实际键。 Unity允许按钮具有负或相反的键。例如,右箭头键为正,而左箭头键为负。您不需要为所有键提供负数 - 为使用操作提供负键是没有意义的。+ * Alt NegativeAlt Positive Buttons是替代键。在这种情况下,您可以启用A和D键,而不是左箭头键和右箭头键。

其他的field主要涉及模拟棒(analog sticks)的功能。为简单起见,此游戏仅使用键盘输入。如果你想让这款游戏成为一款真正的双棒射击游戏,你可以选择这些游戏来制定严格的控制方案。


Accessing Input From Code - 从代码获取输入

现在实际实现控制方案。 在项目浏览器中,双击PlayerController脚本以启动编辑器。

代码编辑器打开后,您将看到第一个脚本。 每个新脚本都包含Start()Update()的空实现。

在第一个{(a.k.a。,“花括号”)下面找一个空白行 - 这就是类定义。 在那里添加以下代码:

public float moveSpeed = 50.0f;

注意:如果您不熟悉编程语言,那么将所有内容完全按照编写方式进行复制至关重要。 任何偏差都会产生错误。 编程语言非常精确,当您使用不正确的大小写或语法时会变得脾气暴躁。

如果您的脚本引发错误,请仔细查看代码以确保您不会错过,忘记或搞砸某些内容。

moveSpeed是一个变量,用于确定英雄在竞技场中移动的速度。 您将其设置为默认值50,您可以稍后在Unity的界面中进行更改。

现在,编写实际的移动代码。 在Update()中,添加以下内容:

Vector3 pos = transform.position;

这段代码只是获取当前GameObject的当前位置 - 在这种情况下,陆战队员因为这是该脚本所附加的 - 并将其存储在名为pos的变量中。 在Unity中,Vector3封装了GameObject的x,y和z,即3D空间中对象的点。

现在是棘手的部分。 在上一行之后添加以下内容:

pos.x += moveSpeed * Input.GetAxis("Horizontal") * Time.deltaTime;
pos.z += moveSpeed * Input.GetAxis("Vertical") * Time.deltaTime; 

移动对象时,它只会在z轴和x轴上,因为y表示向上和向下。 因为有两个不同的输入源(左右为“水平”,向上和向下为“垂直”),所以需要分别计算每个轴的值。

Input.GetAxis(“Horizontal”)Input ManagerHorizontal组件中检索值。 返回的值为1-1,其中1表示正在按下输入管理器中的正按钮。 根据您之前定义的设置,这是右箭头或d键。 类似地,值-1表示正在按下负按钮,这意味着它是左箭头或a键。

无论返回的值是什么,它都会乘以moveSpeed并添加到GameObject的当前x位置,从而有效地将其移动到所需的方向。

Input.GetAxis(“Vertical”)也会发生同样的事情,除了它从Input Manager的垂直组件中检索一个值(表示sdownwup键),将此值(1或-1)乘以moveSpeed并将其添加到GameObject的z位置。

那么Time.deltaTime是什么?该值表示自上次Update()以来经过了多长时间。请记住,每个帧都会调用Update(),因此必须考虑时间差异,或者陆战队员移动得太快而无法看到。

TL / DRTime.deltaTime确保移动与帧速率同步。

这些数字是什么意思?

默认情况下,Unity认为一个点等于一米,但您不必遵循此逻辑。例如,你可能正在制作一个关于行星的游戏,而且这个尺度太小了。为了简化本教程,我们调整了模型的大小,以遵循Unity默认的每米一点。

现在您已经更改了位置,您必须将它应用于SpaceMarine GameObject。在上一行之后添加以下内容:

transform.position = pos;

这会使用新位置更新SpaceMarine GameObject的位置。

保存脚本并切换回Unity。 你可能很想运行你的游戏,但是有一个小问题。 相机未正确放置。

在Hierarchy中,选择Main Camera,在Inspector中,将Position设置为(-9.7,53.6,-56.1),将Rotation设置为(30,0,0)。 我通过手动移动相机并查看右下角的相机预览来确定这些值,直到我对结果感到满意为止。

Camera组件中,将Field of View设置为31。这样可以有效地“放大”视图。

现在是时候让你的游戏进行试运行了。 在编辑器的中心顶部查找播放控件。 单击Play按钮。

注意:您会注意到控件还有两个选项:Pausepause stepper。 暂停可让您暂停游戏。 stepper允许您一次一帧地逐步执行动画,这对于调试动画问题特别有用。

现在,查看游戏窗口并按箭头键或WASD键移动角色。

The Game window - 游戏窗口

游戏窗口是您实际玩游戏的地方。玩游戏时要记住两个生死的细节。

首先,当您开始播放时,界面会变暗,以提供您正在播放模式的可视队列。

第二,当你玩游戏时。您可以更改任何内容(包括更改检查器中组件的值),但是当您停止玩游戏时,所有更改都将丢失。这既是一种好处,也是一种坏处。好处是你有能力调整游戏而没有后果。坏处是,有时你会忘记你处于游戏模式,继续你的游戏,然后由于某种原因,游戏停止。噗!再见!

值得庆幸的是,您可以(并且应该)使播放模式非常明显。选择PC上的Edit \ Preferences或Mac上的Unity \ Preferences以显示选项列表。

选择Colors部分。寻找Playmode色调。单击它旁边的颜色框,然后给它一个明确无误的颜色 - 我更喜欢红色。现在玩你的游戏,看看它是否足够显眼。


Camera Movement - 相机运动

陆战队员的运动只有一个问题:他会从屏幕上滑落。 你希望相机跟随竞技场周围的英雄,所以他不会离你而去。

通过一些脚本编写,您可以保持对陆战队员的关注。

首先,确保您没有处于游戏模式 - 要停止游戏模式,请再次选择play按钮。

在“层次结构”中,单击“创建”按钮,然后选择Create Empty。 将其命名为CameraMount

基本思路是您希望CameraMount表示相机应该关注的位置,并让相机相对于此位置。

最初你希望相机聚焦在太空船的位置,所以让我们将CameraMount配置在与太空船的完全相同的位置。

要执行此操作,请选择space marine,单击Transform组件右上角的齿轮按钮,然后选择Copy Component

然后选择CameraMount,单击Transform组件右上角的齿轮按钮,然后选择Paste Component Values

接下来,将Main Camera GameObject拖动到CameraMount GameObject中。

很好! 现在,当你移动玩家时,你可以移动CameraMount与玩家一起移动,相机将跟踪玩家。 您只需要编写一个脚本来执行此操作。

选择CameraMount后,单击“检查器”中的Add Component按钮,然后选择New Script。 将其命名为CameraMovement,然后单击Create and Add

注意:通过单击Add Component按钮创建新脚本时,Unity将在资源文件夹的顶级创建脚本。 养成在制作或查看资源时将资源移动到各自文件夹中的习惯。

将新文件从assets文件夹的顶级拖到Scripts文件夹中。

双击CameraMovement脚本以在代码编辑器中将其打开。 在类定义下,添加以下变量:

public GameObject followTarget;
public float moveSpeed;

followTarget是您希望相机遵循的内容,moveSpeed是它应该移动的速度。 通过将这些作为公共变量创建,Unity将允许您在Unity编辑器本身中设置这些变量,因此您可以将followTarget设置为陆战队员,并将moveSpeed放在心脏的内容中,您很快就会看到。

现在将以下内容添加到Update()

if (followTarget != null) 
{
  transform.position = Vector3.Lerp(transform.position, 
    followTarget.transform.position, Time.deltaTime * moveSpeed);
}

此代码检查是否有可用的目标。如果没有,相机不会跟随。

接下来,调用Vector3.Lerp()来计算CameraMount的所需位置。

Lerp()有三个参数:3D空间中的起始位置,3D空间中的结束位置,以及介于起始位置和结束位置之间的点的介于0和1之间的值。 Lerp()返回由最后一个值确定的起始位置和结束位置之间的3D空间中的点。

例如,如果最后一个值设置为0,则Lerp()将返回起始位置。如果最后一个值为1,则返回结束位置。如果最后一个值为0.5,则它返回起始位置和结束位置之间的一个点。

在这种情况下,您将提供相机安装位置作为开始,将播放器位置作为结束。最后,将自上一帧速率以来的时间乘以速度乘数,以获得最后一个参数的合适值。实际上,这使得摄像机安装位置平稳地移动到玩家随时间的位置。

保存您的代码并返回Unity。在Hierarchy中选择CameraMount,然后查看Inspector。您将看到两个名为Follow TargetMove Speed的新Field。如前所述,这些是由Unity刚刚添加到脚本中的public变量自动派生的。这些变量需要一些值。

在层次结构中仍然选中CameraMount的情况下,将SpaceMarine拖到Follow Target字段并将Move Speed设置为20

玩下游戏看看发生了什么变化

陆战队员现在是一个真正的超级明星,配有个人摄制组。 当然,他无法转身,他就像Kitty Pryde一样穿过物体,但这些都是你现在无需解决的容易解决的问题。

注意:移动速度越大,相机支架移动到玩家的速度就越快。 越小,摄像机就越“滞后”陆战队员的位置,让玩家“超前”摄像机。 尝试将移动速度更改为较小的值,例如2,看看自己会发生什么!


Adding Gunplay

不幸的是,外交的精细部分在这场比赛的肉食对手身上失去了。 你最好给英雄一些火力,这样他就可以在他非常轻松(可怕的)假期中保护自己。

首先,您需要创建一个子弹。 在“层次结构”中,单击“创建”按钮。 从下拉列表中,选择3D Object\Sphere以在Scene view视图中创建球体。

把它命名为Projectile。 如果仍然选中它,请查看Inspector。 你会发现一堆新组件。

这三个新组件是:

  • 1) Mesh Filter是一个组件,包含有关模型网格的数据并将其传递给渲染器。
  • 2) 网格渲染器(Mesh Renderer)显示网格。它包含许多关于照明的信息,例如投射和接收阴影。
  • 3) 最后,你会注意到球体包含一个球体对撞机(Sphere Collider)。该组件充当GameObject的边界。

由于你希望子弹参与Unity的物理学,它需要一个Rigidbody

幸运的是,你以前做过这件事。单击Add Component按钮,然后从Physics类别中选择Rigidbody。确保取消选中Use Gravity

由于队员将燃烧大量射弹(projectile),因此将其从“层次结构”拖动到项目浏览器中的“预制”文件夹。从层次结构中删除射弹,因为现在它不再需要它作为预制件。

此时,您需要创建一个脚本来启动射弹。在项目浏览器中,选择Scripts文件夹,然后单击“创建”按钮。选择C#Script并将其命名为Gun。双击该文件以启动代码编辑器。

此文件需要在类定义下面的一些属性。添加以下内容:

public GameObject bulletPrefab;
public Transform launchPosition;

同样,当您在脚本上创建公共变量时,Unity会在编辑器中公开这些变量。 您将bulletPrefab设置为刚刚创建的子弹预制件,然后将launchPosition设置为Space Marine枪管的位置。

接下来,添加以下方法:

void fireBullet() 
{
  // 1
  GameObject bullet = Instantiate(bulletPrefab) as GameObject;
  // 2
  bullet.transform.position = launchPosition.position;
  // 3
  bullet.GetComponent<Rigidbody>().velocity = 
    transform.parent.forward * 100;
}

下面进行细分说明:

  • 1) Instantiate()是一种内置方法,可为特定预制件创建GameObject实例。在这种情况下,这将基于子弹预制件创建一个子弹。由于Instantiate()返回一种Object类型,因此必须将结果强制转换为GameObject
  • 2) 子弹的位置设置为发射器的位置 - 您将在短时间内将发射器设置为枪管。
  • 3) 由于子弹上附有刚体(Rigidbody),因此您可以指定其速度以使子弹以恒定速率移动。方向由该脚本所附着的物体的变换决定 - 你很快就将它附着在队员的身体上,确保子弹的行进方向与队员相同。

保存并切换回Unity。在Hierarchy中,展开SpaceMarine GameObject并选择BobbleMarine-Body GameObject

Inspector中,单击Add Component按钮并在组件列表底部附近,选择Scripts。从脚本列表中选择Gun

你会看到你的Gun脚本组件已被添加到队员的身体中。 您还会注意到有两个新字段:Bullet PrefabLaunch Position。 听起来很熟悉吗?

单击Bullet Prefab旁边的圆圈。 在Select GameObject对话框中,单击Assets选项卡。 从结果列表中选择Projectile。 现在你加载了子弹,只需要设置发射位置。

在层次结构中,按住PC上的Alt键或Mac上的Option,然后单击BobbleMarine-Body旁边的显示三角形。 你会看到一个很大的子GameObjects列表。 寻找Gun

选择该GameObject并单击Create按钮。 选择Create Empty Child并将其重命名为Launcher。 这个新的GameObject存在于枪管的中心,代表子弹产生的地方 - 如果你想调整外星怪物产卵的位置,可以随意在场景编辑器中移动它。

保持所有GameObjects扩展并选择BobbleMarine-Body,以便Inspector显示所有组件。 将新的Launcher GameObject拖动到Gun组件的Launch Position字段中。

请注意,当您将GameObject添加到变换字段时,Unity会查找并引用附加的变换。

这是官方的! 队员的枪被锁定和装载。 剩下的就是点火代码。 谢天谢地,这很简单。

切换回代码编辑器并打开Gun.cs

当用户按下鼠标按钮时枪应该发射,当用户释放它时停止。

你可以简单地检查按钮是否在Update()中按下并调用fireBullet()(如果是这样),但是因为每帧都调用Update(),这意味着你的队员每秒最多可以射击60次! 我们的队员可以快速射击,但速度不快。

你需要的是你射击子弹之间的轻微延迟。 为此,请将以下内容添加到Update()

if (Input.GetMouseButtonDown(0)) 
{
  if (!IsInvoking("fireBullet")) 
  {
    InvokeRepeating("fireBullet", 0f, 0.1f);
  }
}

首先,使用输入管理器(Input Manager)检查是否按下了鼠标左键。

注意:如果你想检查鼠标右键,你会传入1,而对于鼠标中键,你会传入2

如果按住鼠标,则检查是否正在调用fireBullet()。 如果没有,则调用InvokeRepeating(),它会重复调用方法,直到您调用CancelInvoke()

InvokeRepeating()需要方法名称,开始时间和重复率。 InvokeRepeating()MonoBehaviour的一种方法。

在那段代码之后,添加以下内容:

if (Input.GetMouseButtonUp(0)) 
{
  CancelInvoke("fireBullet");
}

此代码使得一旦用户释放鼠标按钮,枪停止触发。 保存你的工作并返回Unity,然后玩游戏。

按住鼠标按钮。 你有几天的子弹!

在这一点上,你应该对Unity感觉更舒服。 你有一个带有武器的队员。 您已经学会了以下内容:

  • Components以及它们如何为GameObjects提供行为。
  • Scripting以及如何使用脚本创建自定义行为。
  • Input Manager以及如何从代码中访问它。
  • Game window以及如何测试游戏。

还有很多事要做。 你的可怜的队员无法转过身来看看他背后隐藏着什么。 与此同时,他没有什么可担心的,因为没有外星人攻击他!

后记

本篇主要讲述了一款简单射击游戏示例,感兴趣的给个赞或者关注~~~

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,636评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,890评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,680评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,766评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,665评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,045评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,515评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,182评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,334评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,274评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,319评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,002评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,599评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,675评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,917评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,309评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,885评论 2 341

推荐阅读更多精彩内容