【Unity入门】零基础实现游戏Demo--神鸟大战怪兽
大家好,我是Lampard~~
欢迎来到Unity入门系列博客,所学知识来自B站阿发老师~感谢
(一) 前言
经过了两个月的学习,我们也顺利的完成了入门课程,最后就用一个Demo作为我们的结课句号吧,这篇文章会带大家从0完成这些~~文末会附带项目资源包,一定要看到最后哇 (●'◡'●)
(二) 搭建环境
(1) 下载unityHub
开发第一步那当然是得配置开发环境,我们可以从https:unity.cn,下载我们的unity开发引擎。unity需要通过一个unityHub,来管理开发用到的引擎(编译器)和项目。所以我们第一步是在上述网站上下载一个unityHub
(2) 注册账号和获得开发许可证
在下载玩Hub之后,我们需要先注册一个unity的账号,可以用邮箱或者手机,过程就不表了和其他平台的注册没啥两样 。那么登录了之后就可以了吗?NONONO,我们还需要获得一个unity的许可证,来证明我们的使用目的是学习用途而不是商用
打开Hub,在设置界面选择许可证,点击添加按钮,勾选个人用途就可以免费使用unity进行学习啦。在申请免费个人版许可证之后,可能需要等待个几十秒,然后就可以在许可证页面看到自己申请的许可证了
(3) 下载编辑器(引擎lts版本)
申请许可证后,我们就可以下载我们用到的游戏引擎了,我们可以选择最新版本的引擎,也可以选择LTS类型的引擎。什么是LTS呢?就是long team support的缩写,是官方会长期维护的版本。换言之就是bug比较少的引擎咯。我们现在开始学习,当然就不求新求稳啦~2020和2021的lts随便选一个,我就选择2020的
(4) 创建Unity项目
当我们下载完毕之后,应该会在桌面上看到这两个图标。白白的是我们的unityHub,黑色的就是我们的引擎编译器了。和cocos不同,直接点击编译器是没有反应的。我们需要通过Hub来生成和管理项目,下面我们打开Hub,在项目页签点击右上角的创建按钮
我们看到有2d,3d还有下面两个不知道什么鬼的选项(哈哈哈哈用不上先不管了),我们现在选择3d的项目,然后给项目设置一个存放路径和项目名就可以了
(5) 打开Unity项目
创建完毕之后,返回项目页签就可以在项目页签看到刚才创建的项目
点进去之后,Hub就会帮助你在编译器中打开这个项目,当你看到这个界面之后,恭喜你环境搭好啦~
(三) 导入项目所需的资源
(1)模型资源
我们这个Demo是实现一个类似于飞机大战之类,控制己方射击敌方的小射击玩法。那要实现这个功能,首先就要导入双方的模型资源
我们只需要把文末的资源包拖动到Assert目录下,点击Import就可以了
首先看看我们的主角神鸟模型,它是一个FBX类型的模型:里面包含了一个mesh网格文件,一个materials材质文件和一个png格式的纹理
什么是网格?
我们看到的3D物体,实际上是由一个个小的三角形组成的。所谓网格数据其实就是描述构成模型的一个个三角形,所包含的顶点数据,纹理坐标,法线信息等等的一系列数据
什么是材质?
物体的物质的性质、特征或组成。材质可以是金属、塑料、木材、玻璃、陶瓷、纺织品等等。正确选择材质可以决定物体的质量、外观、特性和使用寿命。材质也可以用于表示3D模型的外观和质感。在计算机图形学中,材质通常用纹理、颜色、反射率、粗糙度、透明度等参数来描述
什么是纹理?
现实生活中,物体很少会遇到纯色的。肯定每一个物体,甚至物体的每一个地方都有区别,而用于呈现它们具有的不同外表的东西就叫纹理
扯远了,我们继续看看怪兽的模型。怪兽的模型由两个部分组成:分别是本体和盔甲。它模型内部有两个和材质,但是它的网格数据是共用的
直接把它们托到层级管理器Hierarchy中就可以生成两个模型对象了
(2)天空盒
首先什么是天空盒?
在实时渲染中,如果要绘制非常远的物体,例如远处的山、天空等,随着观察者的距离的移动,这个物体的大小是几乎没有什么变化的。而实现这种“无穷远”的背景技术就是天空盒技术
unity自带了一个蓝天黑地的天空盒,为了美观一些,我们可以替换天空盒的纹理和材质
首先点击Window餐单栏下面的Rending->Lighting子菜单,然后在Enviroment页签下,找到天空盒定义材质和纹理的地方,把我们实现准备好的天空盒材质和资源替换上去即可
(3)子弹
既然是大神鸟打小怪兽,那肯定得有一个攻击用的子弹。至于子弹我们就简单用一个Unity自带得球体就可以了
我们可以从界面左上方的GameObject处选择生成的对象,也可以在层级控制Hierarchy处鼠标右键选择生成物体,选中Sphere就可以创建一个球体。修改一下命名和大小就可以得到子弹对象了
(四) 搭建脚本开发环境
(1)下载visual studio
接下来就要编写脚本了,首先我们要搭建好开发环境。在我们下载unity编译器的时候,会让我们选择当前unity编译器搭配的vs编译器。我们最好就直接勾选上,或者可以自己手动下载vs,在vs的installer里勾选unity引擎开发需要的环境
(2)unity中设置脚本编译器
下载好了之后,我们要在unity中更新vs作为脚本编译器。方式很简单,打开编译器,选择Edit -> Preferences目录 ,在 External Tools 页签里,选择 VS 作为脚本编辑器
(3)设置随脚本修改重新编译
为了方便之后的开发调试,我们需要设置每当脚本修改了之后,unity自动帮我们编译这个脚本,让改动可以实时的生效。选择Edit -> Preferences目录 ,在 General 页签里,把Script Change While playing 选项调整为:Recompile After Finished Playing即可
(五) 碰撞检测
(1)子弹移动脚本
想要实现子弹从神鸟往怪兽方向移动,我们可以通过创建一个C#脚本,在脚本中每一帧更新子弹的transform组件位置,最后把这个脚本挂在子弹对象上即可
其中Translate方法可以帮助我们便捷的调整对象的位置,Time.deltaTime可以访问到当前帧距离上一帧的执行时间,因此帧更新位置的代码如下:
void Update()
{
float DisPreSec = 6f; // 移动速度
this.transform.Translate(0, 0, DisPreSec * Time.deltaTime);
}
下面看看效果:
(2)Collider组件
子弹径直从怪兽身上传过去,显然不是我们想要的效果。若要实现子弹击中怪兽,就和怪兽一并消失的效果,那我们就需要监听碰撞检测
监听碰撞检测需要三个条件:首先双方物体对象都有碰撞体Collider组件,Unity提供了以下的碰撞体组件选择
1. Box Collider(盒子碰撞器):一个基于矩形的碰撞体,用于模拟长方体或立方体物体的碰撞。
2. Sphere Collider(球形碰撞器):一个基于球形的碰撞体,用于模拟球体物体的碰撞。
3. Capsule Collider(胶囊碰撞器):一个基于胶囊形状的碰撞体,用于模拟某些具有胶囊形状的物体的碰撞,比如人物角色。
4. Mesh Collider(网格碰撞器):一个基于游戏对象模型的碰撞体,用于模拟复杂的几何形状的物体的碰撞,比如地形、建筑等。
5. Terrain Collider(地形碰撞器):一个基于 Unity 地形的碰撞体,用于模拟地形的碰撞。
6. Wheel Collider(车轮碰撞器):一个专门针对车辆的碰撞体,用于模拟车辆的轮子与地面的碰撞。
7. Character Controller(角色控制器):一个专门为人物角色设计的碰撞体,用于模拟人物角色的移动和碰撞。
子弹是Unity自带的3d物体,本身带有一个碰撞体组件。我们只需要给怪物模型也加上碰撞体就可以了,我们可以选择一个箱体的Colider,调整其大小直至覆盖住怪物即可(绿框框),下面是添加过程:
(3)设置触发器和运动学刚体属性
刚体我们知道是物理学中研究的一个物体对象概念,那运动学刚体是什么呢?
运动学刚体不受物理引擎的计算和影响,而是由开发者手动控制它的运动。运动学刚体可以设置为运动、旋转或缩放,但不会受到重力、碰撞等物理效果的影响。运动学刚体通常用于模拟精确的动画或特效效果,或者用于实现一些特定的游戏机制
给子弹添加Rigidbody刚体组件,里面有一个可以选择Is Kinematic的参数,选中就可以让子弹对象成为一个运动学刚体
然后再把子弹Colider组件中的isTrigger给勾选上,就可以监听碰撞事件的发生
(4)设置碰撞监听函数
在前面这些都准备好之后,我们就可以给子弹对象加上碰撞监听函数了
isTrigger 是 Collider(碰撞体)组件中的一个属性,用于指定碰撞体是否为触发器。
当一个碰撞体的 isTrigger 属性被设置为 true 时,该碰撞体就不会影响游戏对象的物理运动,也不会产生碰撞效果,而只是用于检测游戏对象是否进入了该碰撞体的范围内。当游戏对象进入触发器时,就会触发 OnTriggerXXX 系列函数(比如 OnTriggerEnter、OnTriggerStay、OnTriggerExit)
因此在子弹脚本中添加OnTriggerEnter方法之后,在碰撞发生时就会被监听到事件的发生。 再用Destory静态方法,把碰撞体(子弹)和碰撞对象(怪兽)一起销毁即可
看看效果:
(5)自毁
子弹命中怪兽后能够正常的销毁,但是正常游戏中应该没有什么怪兽会呆呆的站在那里让你打。那些打不中怪物的子弹应该加上一个自毁方法,来避免内存泄漏
此时我们需要用到unity的计时器Invoke类
Unity 的 Invoke() 方法是一种用于延迟执行某个方法的方式。Invoke() 方法可以在指定的时间(以秒为单位)后执行指定的方法
Invoke() 方法的语法如下:
```
Invoke(string methodName, float time);
```
其中,`methodName` 是要执行的方法的名称,`time` 是要延迟的时间(以秒为单位)
因此我们调用Invoke方法,设定一个自毁时间,若时间到了子弹对象还存在,则去销毁它
看看效果:
(六) 玩家主控逻辑
(1)发射逻辑
子弹的逻辑我们已经写好,下面就要开始制作神鸟的逻辑了。首先需要给神鸟创建一个C#脚本,命名就叫PlayerLogic好了
紧接着,给神鸟脚本加上第一个功能,发射子弹。需要怎么做呢?首先声明一个子弹的对象用于克隆
[Tooltip("子弹节点的预制体")]
public GameObject bulletPrefab;
然后编译器选中这神鸟对象,就可以看到我们刚才声明的属性,把已经制作好的子弹拖过去就可以被访问到了
紧接着我们可以定义一个Fire方法,通过引擎自带的Instantiate静态方法,生成子弹对象
private void Fire()
{
// 实例化一个子弹节点
GameObject node = Instantiate(bulletPrefab);
}
把Fire方法在Start的时候调用,就会在游戏开始的时候被执行一次,也就是发射一次
void Start()
{
Fire();
}
但是这一点都不猛,为了让主角火力更猛一些,我们可以给它安排一个突突冒蓝火的加特林,实现一个连发功能,具体做法就是调用我们的InvokeRepeat方法,实现方法循环调用
void Start()
{
InvokeRepeating("Fire", 0.1f, 0.1f);
}
比如这样我就可以0.1秒开一炮,看看效果:
(2)移动逻辑
紧接着要给神鸟加上移动逻辑,希望它和很多游戏一样,通过wsad键,进行上下左右移动
首先移动的逻辑我们可以和子弹对象一样,通过translate方法实现。问题的关键就是如何监听键盘按下的事件了:
键盘可以获取它的按下,长按和抬起状态。分别需要调用Input.GetKeyDown,Input.GetKey 和 Input.GetKeyUp 来实现
比如这样就可以监听W键的按下和抬起:
void Update()
{
if (Input.GetKeyDown(KeyCode.W))
{
Debug.Log("正在执行W键的按下");
}
if (Input.GetKeyUp(KeyCode.W))
{
Debug.Log("正在执行W键的抬起");
}
}
在神鸟脚本中的Update方法里加上这样的代码,就可以实现前后左右移动的功能:
看看效果:
(3)修改子弹生成对象的
不难发现,神鸟是能动了,但是子弹还是呆在原地,我们需要在子弹生成的时候,把子弹生成的位置设置成神鸟的位置即可
private void Fire()
{
// 实例化一个子弹节点
GameObject node = Instantiate(bulletPrefab);
// 调整子弹的发射结点
node.transform.position = this.transform.position;
}
(七) 怪物脚本
(1)蛇皮走位
到了最后一步,就是给怪物也加上脚本逻辑了。首先要实现的就是怪物的蛇皮走位,毕竟呆呆的站在原地让人打也太没意思了
过程分两步,首先控制怪兽往Z方向(玩家方向)定速移动
然后,需要让怪物随机的左右移动来躲避子弹。随机效果的实现可以定义一个速度的数组,然后定时利用Random.Range方法,从速度数组中选择一个,然后怪兽就按照这个速度在X方向进行移动即可
和子弹相似,若怪物没有被击中,我们不能让怪物永远的存在,因此可以判定怪物的位置,若已经超出了击中范围,就自动销毁
好的,我们来看看效果:
(2)批量生产怪物
下一步就是批量生成怪物,之前我们把批量生成子弹的逻辑写在玩家身上,那批量生成怪物写在哪里比较好呢?
一般的项目都有一个main方法,我们也可以创建一个Main脚本,把控制游戏流程的东西放在里面。生成流程与子弹相似,就不重复赘述了
MainLogic随便创建一个空节点挂上去就可以生效了
看看目前的效果,怪物可以批量创建,然后子弹击中也可以令怪物消失
(3)艺术就是派大星
至此我们的主要逻辑就写的差不多了,但是现在的击中效果未免也太弱了。有一位名人说过,“艺术就是爆炸”
为此我们可以给子弹击中的时候加上绚丽的粒子特效效果。特效的资源我们已经放在了Effect的目录下方
使用的方法也很简单,首先需要在子弹脚本中声明一个粒子特效对象,在编辑器中把特效挂上去,子弹脚本就可以访问到特效资源了。
然后和普通的预制体一样,在碰撞发生的时候(OnTriggerEnter),通过Instantiate方法创建,并把其位置设定成子弹的位置即可,注意单次播放的粒子特效播放一次之后就自动销毁,无需手动Destory
(4)背景音乐
为了更有趣味一些,我们还可以给游戏加上背景音乐。其中用到的是AudioSource组件
audioSource是指音频源,它是Unity中AudioSource组件的一个属性,用于存储音频剪辑或音频资源的引用,并控制播放、暂停、停止、音量等音频的相关属性。在Unity中,AudioSource组件可以附加到游戏对象上,使其能够播放音频文件,例如背景音乐、音效等
至于使用方法就更简单了,首先右键生成组件,挂在主控结点上。然后把事先准备的MP3资源挂在AudioSource组件的autoclip上即可
好啦,看看DEMO的最终成果吧:
真是泰酷辣!!!
(八)结语
至此入门的Demo已经完成了,感谢这两个月的陪伴~
但是!很快我们就会续更基础,和高级Unity系列的文章,敬请期待!!!
下载资源链接在这里:【Unity入门Demo项目资源】
点赞,关注!!!