实战:用Unity快速开发太空飞机大战(上)
让我们通过Unity动手实践,开发一个简单的太空飞机大战游戏。接下来,我将详细介绍开发过程。
最终效果
在游戏中,玩家可以控制己方战机,向目标敌机发射子弹,体验“打飞机”的乐趣。让我们逐步实现这个太空飞机大战游戏。
开发步骤
1. 新建工程与导入资源
新建一个打飞机的Unity工程,并创建好资源分类目录。然后导入飞机的FBX模型文件、贴图,以及射击和爆炸等声音文件。
2. 新建场景
新建一个名为 game.unity 的场景,后续大部分工作将在这个场景中完成。
3. 创建背景模型与材质
为了让游戏场景背景更真实,我们希望显示一个火星球和星空的效果。具体操作如下:
- 新建一个平面体
Plane作为火星背景模型。 - 创建一个材质球并命名为
Background,将之前导入的火星贴图文件指定给该材质球。
4. 关联材质与模型
Unity 中几乎所有的关联操作都可以通过拖动方式完成。现在,我们选中刚创建的 Background 材质球,将其拖放到火星模型上,完成材质与模型的关联。
5. 创建星空效果
创建另一个平面体,放置在火星后面,用于制作星空效果。同样地,创建一个星空材质球,设置好对应的贴图(操作与火星材质球设置类似),然后将星空材质球拖到新的平面体上。此时,我们就可以看到星空中的火星了。
6. 实现星空缓动动画
为了让星空在游戏运行时产生缓动效果,给人一种星空在移动的感觉。这里暂不详细介绍 UV 动画以及动画制作过程,我们准备了一个 .anim 动画文件。选中星空模型,添加 animation 组件,并将动画文件设置为该 .anim 文件,从而实现星空的缓动效果。
7. 调整视角
经过前面的步骤,游戏的太空背景效果基本处理完成。接下来,我们需要调整视角,从上向下展望火星和星空。具体操作如下:
- 调整摄像机的视角和视野大小。
- 选中
Main Camera,选择GameObject里的Align With View,使摄像机视角与当前视图一致。此时,我们就可以看到太空的火星和星空效果了。
8. 创建己方战机
现在,我们要创建己方战机,这是玩家要控制的主角。将准备好的主角战机 Fbx 模型拖入场景中,并调整战机的朝向。
9. 让战机动起来
要让战机动起来,我们主要会用到 Input 类和 Transform 组件。Input 类包装了输入功能,包含很多键盘、鼠标或触控操作函数;Transform 组件主要与游戏体的移动、旋转、缩放有关。
具体操作如下:
- 选中战机模型,为其添加一个脚本。在脚本中,我们需要实现以下功能:
- 控制战机的上、下、左、右移动,并控制移动速度。
- 控制战机发射子弹,以及设置子弹的发射间隔。
- 控制战机的生命值,设置战机爆炸声音和爆炸效果等。
- 添加脚本时,选中战机,将对应的脚本拖到战机上即可。
10. 创建子弹
子弹是游戏中需要重复使用的游戏体,因此我们需要创建 prefab。具体步骤如下:
- 将子弹 Fbx 模型拖入场景中。
- 新建一个子弹的
prefab,选中Hierarchy中的子弹游戏体,将其拖入prefab上。 - 子弹的主要功能是控制飞行、造成伤害值以及自身的生存时间。我们需要给子弹添加脚本。
- 完成上述操作后,可删除场景里的子弹。
11. 让战机发射子弹
设置 Player 脚本参数,将我们创建的子弹 prefab 赋值给 rocket 参数,并设置发射间隔为 0.1s。此外,还可以为战机发射子弹添加声音。需要注意的是,凡是要发声的物体,都需要添加 audio source 组件。
12. 子弹逻辑处理
子弹的主要行为是飞行然后消失,消失分为两种情况:一是碰撞了敌机,二是生存时间到了自动消失。这里涉及到碰撞和 OnTriggerEnter 事件,后续会详细说明。战机的主要行为是移动、通过输入控制发射子弹,并伴随射击声音。在 Unity 中,使用 Instantiate 函数进行实例化,而不是常用的 new。
13. 运行测试
目前,我们已经有了主角战机和子弹,但还没有其他交互。运行游戏,我们可以看到实例化出来的子弹以及其被销毁的过程。
14. 创建敌战机
敌机也需要重复使用,因此先创建敌机的 prefab,并为敌机添加控制脚本。在这个阶段,我们先创建简单的敌机,它不具备攻击性,不会发射子弹,只能移动,我方战机可以发射子弹打掉它。
15. 处理碰撞事件
前面提到了碰撞和 OnTriggerEnter 事件,现在我们需要运用这些来处理打掉敌机的逻辑。具体操作如下:
- 给敌机增加
Box Collider组件,这是一个立方体碰撞组件,选中trigger使其具有触发作用,这样就能使OnTriggerEnter事件有响应。 - 给敌机增加刚体组件。所有参与物理计算的游戏体都需要有一个刚体才能正常工作。不选择
use Gravity使其不受重力影响,选中Is Kinematic使其运动不受物理模拟影响。这些改动会自动更新与prefab一致。 - 同样地,按照上述方法给子弹、主角战机也添加
Box Collider组件和刚体。
16. 设置标签与碰撞逻辑
设置好敌机、子弹、主角战机的 tag 标志,这是在各脚本 OnTriggerEnter 中需要处理的逻辑:
- 敌机碰到子弹会损失生命,直到生命值为零就自动销毁;敌机撞到主角战机直接销毁。
- 子弹碰到敌机就自动销毁。
- 主角战机碰到非自己射出的子弹就减少一条命,直到生命值为零则自动销毁,游戏结束。
17. 防止敌机无限存活
为了防止敌机未被消灭而一直存活下去,我们可以在屏幕下方放置一个空的碰撞体,当敌机碰到它时就自动销毁。
18. 游戏初步完成
通过以上所有步骤,我们已经可以控制战机移动、发射子弹攻击或直接撞击敌机。至此,一个太空飞机大战游戏的初期形式已基本完成。
后续扩展建议
在这个基础上,我们可以进行以下扩展:
- 超级敌机:创建继承自普通敌机的超级敌机,它将具备攻击能力,生命值更强,可以自动朝主角战机发射子弹,被其子弹命中会减少主角的生命值。
- 敌人生成器:实现敌人生成器,自动生成敌机。
- 游戏信息展示:使用 GUI 来展示游戏信息,如战机生命值、当前得分、游戏失败状态等。
- 新场景与开始按钮:添加一个
start.scene新场景,增加开始游戏按钮,点击后进入game.scene。 - 战机移动控制改进:除了使用方向键控制战机移动外,增加鼠标移动控制,方便将游戏发布到手机上。
遇到的问题与解决方法
在开发过程中,可能会遇到一些问题。例如,我在确认已经给子弹、敌机、主角战机都添加好了刚体等组件,也激活了碰撞,但运行时总是不能触发 OnTriggerEnter 事件,导致无法正常“打飞机”。后来发现是子弹、敌机、主角战机这三个游戏体的 position 里的 y 值不一样导致的。虽然这是一个简单的错误,但可能很多时候容易被忽略,所以需要特别注意。
结束语
这个简单的游戏涉及到 Unity 制作游戏的很多基础内容,包括 Unity 编辑器的基本使用、资源管理、编写控制脚本、添加各种组件、声音处理、使用物理功能等,还有碰撞处理、prefab 的使用等。除了上述扩展建议,我们还可以为这个游戏添加更多细节要素,提供更好的流程体验。
待续...