美文网首页我的世界Unity3Dunity官方教程合集
Unity官方实例教程 Space Shooter(二)

Unity官方实例教程 Space Shooter(二)

作者: Zui | 来源:发表于2015-11-07 12:42 被阅读25905次
    Space Shooter 太空射击

    传送门

    Unity官方实例教程 Space Shooter(一)
    Unity官方实例教程 Space Shooter(二)
    Unity官方实例教程 Space Shooter(三)
    Unity官方实例教程 Space Shooter(四)
    Unity官方实例教程 Space Shooter(五)

    前言

    游戏截图

    Unity官方实例教程 Space Shooter(一)中,我们学会了:

    • 如何下载和导入资源
    • 如何设置游戏视窗大小
    • 添加了飞船和飞船喷射效果
    • Capsule Collider和Mesh Collider的用法

    但是我们还没有为游戏添加任何的操作,现在还只是一个可以看,但不能玩的版本,所以今天我就让游戏可以玩起来!

    你将学到什么?

    • 如何控制飞船移动
    • 如何限制飞船的移动范围
    • 如何整理公共变量
    • 添加游戏背景
    • 如何创建一个新材质
    • 如何让飞机发射子弹

    一、调整摄像机的位置

    我们进入Game窗口,可以看到现在飞船是出于屏幕的正中间的,对于我们最终的游戏来说,这不是一个合适的位置,所以我们首先调整一下摄像机的位置,来改变飞船在屏幕中的位置

    这边其实也可以调整飞船的位置,来达到同样的目的,但是让飞船处于(0,0,0)的位置,会利于我们之后的制作,所以本例中我们采用调整摄像机的位置的方法来实现

    我们选中Main Camera,然后将其的PositionZ值调整为5,然后我们看一下飞船的位置,如下:

    飞船的位置

    这是一个不错的位置,接下来我们便可以来实现飞船的移动功能了

    二、控制飞船移动

    为了实现飞船的移动,首先我们给飞船也就是我们的Player添加一个脚本(Script),关于如何添加脚本请参见Unity官方实例教程 Roll-a-Ball(一),在这里我们将脚本的名字命名为PlayerController,然后我打开脚本,添加以下代码:

    完整的代码
    • 首先我们定义了公共的变量speed
    • 然后我们用两个变量moveHorizontalmoveVertical记录玩家输入的方向数据
    • 然后我们新建一个Vector3类型的变量movement,并且将moveHorizontalmoveVertical分别赋值给movementXZ
    • 最后我们获取Player的刚体的速度属性,将movement乘上speed的值赋给它

    代码写完之后,我们保存一下代码,然后回到Unity编辑器,将speed设置为10,接着运行游戏来检测我们刚刚的代码是否起到作用了。如无意外,现在我们可以控制飞船上下左右移动了!

    飞船移动

    不过现在飞船移动好像不是那么的生动,我们在给飞船左右移动的时候,让飞船整个身体倾斜一点,这样更加性感,我们再次打开脚本,增加以下代码:

    完整的代码
    • 首先我们添加一个公共变量tilt,来设置飞船倾斜的幅度
    • 然后我们获取Player刚体属性的rotation,将我们移动的速度x值乘上-tilt赋值给rotation属性

    关于Quaternion的详细信息有兴趣的朋友可以去查阅官方文档,后面会出专门的文章来详细讲解,这边就不做详细介绍了,大家只需要知道这句话的作用就是实现飞船左右移动时的倾斜功能

    代码写完之后,我们保存一下,然后回到Unity编辑器,将tilt设置为5,接着运行游戏,我们就可以检查刚刚的代码是否起到作用,如无意外,飞船左右移动的时候就会有倾斜效果了

    倾斜效果

    三、限制飞船的移动范围

    我们实现了飞船移动功能后,会发现一个问题,就是飞船可以移动到屏幕外面去,这样玩家就看不到飞船了,这不是好的体验,就像马航失联一样,所以我们需要限制一下飞船的移动范围,让它无法飞出我们的屏幕外

    让我们来思考一下,如何来限制飞船的移动范围呢?首先我们飞船的移动范围,换句话说就是飞船的Position属性,而它的范围呢,就是我们的屏幕边界,由于我们游戏视角是俯视角,飞船的Y轴位置不会变,所以我们只需限制飞船在X和Z轴上的位置即可,我们在编辑器拖动飞船到屏幕的最左边,可以看到飞船的X大约在-6左右,我们使用同样的方法,可以测试飞船在X和Z轴上的范围分别是(-6,6)和(-3,8)。

    接下来我们看看如何在代码中来限制飞船的位置:

    完整的代码
    • 首先序列化了一个Boundary类,用来保存飞船在X和Z轴上的范围,也就是xMin、xMax、zMin、zMax
    • 然后我们定义了一个变量boundary
    • 最后我们获取飞船的位置属性,然后通过Mathf.Clamp来确保飞船在X和Z轴上的范围处于我们设定的值内

    将xMin、xMax、zMin、zMax整合到Boundary类里面,是方便分类管理公共变量,如下图:可以通过小三角来收起/展开,这样让公共变量更加整洁


    Paste_Image.png

    写完代码后,我们保存一下,然后回到Unity编辑器,将xMin、xMax、zMin、zMax的值分别设置为(-6,6,-3,8),然后运行游戏测试一下,就可以发现,现在飞船无法跑出屏幕外了,Nice!

    四、添加游戏背景

    和官方视频不同,我们这边到这一步才添加游戏背景,原因是游戏背景和后面马上要讲到的子弹,都用到了同一个GameObject——Quad,所以两个东西放到一起来讲
    首先我们新建一个Quad对象,然后进行两个标准动作,将名称命名为BackGround,新建成功后,我们在Game视窗中可以看到,没有任何变化,为什么呢?我们回到Scene视图来看一下,Quad到底是个什么东西

    Quad

    我们可以看到,Quad就是一个类似平面(Plane)的对象,它使垂直与摄像机的,所以我们看不到他,所以我们需要将它在X轴上旋转90°,然后我们就可以在Game视窗中看到了

    Paste_Image.png

    我们观察一下BackGroundInspector属性,由于我只是做背景用,所以Mesh Collider我们根本不需要,这里我们就将该组件给移除掉

    Paste_Image.png

    接下来我们将背景图片资源,直接拖入BackGround里面,Unity自动为我们生成了一个材质,此时我们可以看到BackGround变成了如下的样子:

    Paste_Image.png

    这就是我们的背景,额,作为一个背景,它好像还是有很多问题,太小、太暗,比例失调,所以首先第一步,我们就是将它的大小调整到合适的尺寸,我们选中背景图片资源,观察一下他的信息

    背景图片资源信息

    我们可以看到,背景图片的尺寸为10242048,为了让图片比例不会失调,我们需要将BackGround*的X设置为Y一半,我们将XY分别设置为(15,30)

    Paste_Image.png

    我们可以看到,现在BackGround的比例已经正常了,大小也合适,但是图片还是太暗了,这是由于我们选中的材质渲染模式有关系,
    我们将Shader修改为Unlit/Texture后,图片颜色就会变得正常了

    **Shader**修改为**Unlit/Texture**

    最后一步,作为背景,我们发现它有一部分将飞船给遮挡了

    飞船被遮挡了

    所以我们需要将背景往下移动一些,而且由于我们的摄像机是选用的正交模式,所以背景下移并不会改变他的显示效果,我们将BackGround的Position Y设置为-10,这样背景就不会在挡住飞船了

    五、制作子弹

    为了视觉效果和逻辑分离,我们首先新建一个空的GameObject,命名为Bolt,然后继续新建一个Quad,命名为VFX,将VFX拖入到Bolt下面,然后我们选中VFX,把它的Rotation X设置为90,同样的,作为Quad,我们也需要像背景一样,将一个图片显示在上面,但是,这里我们和设置背景图片不一样,我们使用一种新的办法来设置,首先我们新建一个材质

    新建材质

    首先我们选中Create->Material,创建一个新的材质,命名为fx_Bolt_orange

    新建材质

    然后我们选中刚刚新建的材质,修改它的Shader模式为Particles/Additive

    设置Shader

    然后将子弹的图片和材质关联起来,如下图:

    关联子弹图片

    最后我们将我们做好的材质拖入VFX中

    关联VFX

    我们便可看到子弹的效果做好了!

    子弹效果

    给子弹添加碰撞

    一开始我们说了要视觉效果和逻辑分离,所以我们移除VFX中的Mesh Collider组件,然后给Bolt添加刚体和胶囊碰撞(Capsule Collider),同时按下图设置他们的属性:

    刚体和胶囊碰撞的属性设置

    让子弹飞一会儿

    到这里,子弹的视觉效果和物理属性我们都已经设置好了,下一步我们让子弹可以在发射后往前移动,如果子弹不能移动那还怎么打到人呢?
    所以我们给Bolt添加一个新的脚本,命名为Mover,然后打开并编辑它,如下图:

    完整的代码
    • 首先我们定一个公共变量speed用来调节子弹飞行的速度
    • 然后我们在子弹生成时赋予它一个往前的速度

    写完代码后,我们保持一下,然后回到Unity编辑器,将speed速度设置为20

    制作成Prefab

    做完子弹的所有准备工作后,我们将Bolt制作成一个Prefab(预制件),方便以后使用

    制作成Prefab

    最后我们边可以运行一下,看到子弹飞出去的效果了

    子弹飞行效果

    六、飞船发射子弹

    现在我们有了飞船,有了子弹,下一步就应该把它们联合起来,让飞船可以发射子弹,那么开始之前,我们思考一下,要实现飞船发射子弹的功能,我们需要一些什么?

    • 首先我们要知道子弹从哪里发射
    • 然后我们需要检查用户按键,来接受发射信号
    • 然后我们需要设置子弹发射的频率
    • 然后我们还需要知道如何生成一个子弹

    我们一个个来看

    设置子弹发射点(Shot Spawn)

    在实现子弹发射之前,我们将场景中现有的Bolt删除,因为我们不需要他了

    首先我们新建一个空的GameObject,命名为Shot Spawn,作为飞船的一个武器挂载点,确保所有的子弹都是从这个点出发,然后我们把Shot Spawn拖入到Player下面,并调整Shot Spawn的位置到合适的点,本例中置为飞船前方就可以了,如下图:

    发射点的位置

    实现发射功能的代码

    然后我们打开PlayerController脚本,新增以下代码:

    完整的代码
    • 首先我们定义一个私有变量nextFire,用来记录下一发子弹的时间
    • 然后我们定义一个公共变量fireRate,用来控制子弹发射的间隔时间
    • 接着我们定义一个公共变量shot,用来保存我们发射的子弹Prefab,也就是告诉程序,我们发射的是哪个子弹
    • 然后我们定义一个公共变量shotSqawn,用来保存子弹的发射点,也就是告诉程序,子弹从哪里发射出去
    • 接着我们在Update函数中,判断用户是否有按下Fire1键,这边的Fire1键就是键盘上的左Ctrl键和鼠标左键,同时当前时间超过我们下一发子弹所需的时间,换句话来说,这个if的作用就是确保我们武器没有在冷却时间时按下发射键,才会发射子弹
    • 当if条件通过后,我们先记录下一发子弹的时间,然后通过Instantiate方法生成一发子弹,他有3个参数,一个是发射的对象,一个是发射对象的position,一个是发射对象的rotation

    写完代码后,我们保存一下,然后回到Unity编辑器,并分别设置我们刚刚定义的几个公共变量,如下:

    设置公共变量

    所有操作做完后,我们边可以运行游戏,看看实际效果了!

    发射子弹效果

    下集内容

    在下一集,我们将学会:

    • 如何回收子弹
    • 如何创建障碍物
    • 如何通过代码创建无尽波数的障碍
    • 如何实现子弹击碎障碍功能

    相关文章

      网友评论

      • 89b3aee77553:为什么我按下ctrl后,子弹一次发好几个,而不是按一下出一个
        6ea75b4f5eb8:@sunshine_c72c 子弹间隔时间没有设置吧fire rate
      • 67e44850551d:为什么我发射不了子弹,代码是一样的啊
      • unrpyc:为什么,我的飞船不会发生偏移,代码是一样的啊
        97721be1685b:@我们一起_615f 你看下FixedUpdate方法是不是写成fixedUpdate了,首字母要大写的
        e09a496263ef:我也是
      • 4d09a25c6d9c:为什么我的子弹会延迟一下才发出来 就是会在发射点停一会
        4d09a25c6d9c:@七月kirino 啊知道了 我的子弹位置没reset 然后给子对象也加了刚体和碰撞器
      • b69a9dd9afe7:初学者问答主一个问题,这个可以应用在5.2.3上吧
      • b804e8ffabda:- = -博主你好,我在做回收子弹的时候,当第一发子弹到达边界触发退出时销毁后,后续就无法发出子弹了,并报错找不到Gameobject 。。代码都完全一样
      • 338947714874:博主你好,我按你的教程做完第二步后发现一个问题,飞船静止的时候,发射子弹,子弹是从飞机正前方发射的,但是飞机在左右移动的时候,子弹不是从飞机身上发出的而是有很大的偏移,距离飞机很远的地方发射。好像是跟设置Tilt(飞船倾斜)有关系,Tilt值越大,子弹发射位置的偏移越厉害。请问是否是我代码有问题?
        338947714874:哦,貌似是我的 Shot Spawn 的位置的y轴没设置好导致的
      • 6e5a1f94aa4b:在DestroyByContact中的if判断条件里的other.tag 不起作用,还是一运行就炸。我改成other.gameObject.name 了才行,这是为什么呢
        Zui:@六月的韵味 是否有个GameObject设置对应的tag呢?
      • acd20f96c576:另外我们在设置VFX的时候将rotation的x轴设为90,而在最后一行的代码里,我们发射出来的VFX使用的rotation却是shotspawn的,如果不把shotspawn里x轴的rotation设为90,那么发射出来的子弹会因为贴图垂直于相机而看不到。
      • acd20f96c576:5.4版本使用答主的子弹移动(move)代码会出问题,将transform.forward改为vector3.forward解决,原因是VFX在翻转后Z轴的方向和世界坐标的z轴坐标不一样。
        c6804335b625:特意过来评论下,这不是5.4版本的问题,作者在这里的代码也没有问题。导致BUG的是脚本绑定对象的问题。这里不能把mover脚本绑定在VFX下(原文也没有这样做),VFX沿着X轴翻转了之后Z轴变了,但是blot的坐标轴没改动,因此mover.cs绑定到bolt,并且代码中使用transform.forward是正确的。
        另外,就是如果直接把mover.cs绑定到VFX,在下两章会导致另一个问题,即子弹与岩石相撞之后,判定相撞的对象是VFX而不是bolt,这在后面回收的时候只回收了VFX而没有回收bolt。(这个BUG在我找了一圈问题之后才明白)。
        楼上@stezpy 删除VFX其实并不合适,这样没有实现“视觉效果与逻辑的分离”。
        stezpy:@rousi 其实是可以的,我也有同样的问题,是因为我把脚本添加给了bolt下的vfx才会让子弹在x方向移动,把vfx的脚本删了直接加在bolt下可以解决
        7f800587bb44:@THExChaos 你解决了我的问题,按教程中的代码,子弹在X 轴方向移动,真尴尬、、、
      • 11af599fbe12:请教大神,为什么我把rigidbody和capsule collider添加到子弹Quad(VFX)上,而不是它的父空对象Bolt上,就不能运行呢??而且VFX中capsule collider的direction设置成z-axis之后,它的capsule collider方向是向上的??求教 @Zui
        Zui:@宁宁很happy 我试过将那两个组件放到VFX对象上,是可以运行的,不知道你那边具体是什么情况
      • 记录卡:请教博主,Boundary 为什么必须是可序列化的??
        Zui:@deyu 序列化是为了在编辑器里面属性布局看起来更加简洁,增加可读性,不是必须的
      • Zui:A:用GetComponet<Rigidbody>.position和GetComponet<Transform>().position会是一样的效果,你用两者任一个都可以,但是做类似这种功能用Rigidbody会好一些
        B:那是因为飞机的速度在FixedUpdate函数里面会不停的更新,所以你在Start里面设置的速度,会在游戏运行中,在FixedUpdate里面改变,而你没有输入,所以飞机的速度就是为0的
        C:这个道理和B一样的
      • ec9472e4956d:讲的很棒!请教下 A.为什么控制飞船移动不超出屏幕 是 GetComponet<Rigidbody>.position 而不是 GetComponet<Transform>().position B.为什么我在 PlayerController里的 start方法里 写 GetComponent<Rigidbody>().velocity = transform.forward * 10 运行后 飞机不动啊! 多谢! c. 子弹给个速度就一直动下去了 为什么 主角飞机 按ASWD键 动一下 不按 会自己慢慢停下来啊? 刚学UNITY 比较菜 见笑了 :)
      • 2e6096884513:讲得很棒,有个初学问题想问博主,我按照第一个脚本照打了一遍,可是运行了模型无论按wasd还是上下左右都没有动,请问是什么原因呢?
        e09a496263ef:什么问题
        674e33d56e61:@franky_yao 是什么问题??!~
        2e6096884513:@franky_yao 已经找到问题了
      • 9bdd79925da4:博主的教程里,镜头的position应该再设置一个正方向上的y值,否则的话镜头在player下方是看不到
        我不太明白镜头的size参数是什么意思
        如果size是10,是600*900的分辨率,意思是每个单位size表示60*90的区域么
        还有gameobject里position里的x,y,z是以什么为标准的,每个position里的值是什么意义,和分辨率是如何对应的。
        希望博主有时间的话能指点一下,十分感谢楼主的教程。
        9bdd79925da4:@Zui 谢谢博主,讲的很好
        Zui:@zicecream 1、镜头的size含义为屏幕高度的一半,不过单位不是像素而是unit坐标,即通过pixels to units换算的坐标。例如:屏幕高度为640,pixels to units为100的情况下,orthographic size为640/2/100 = 3.2,可以参考一下这篇文章http://www.cnblogs.com/flyFreeZn/p/4073655.html,理解size和分辨率之间的换算关系就会明白怎么控制最终显示在玩家眼前的画面尺寸了
        2、GameObject里的Position的X,Y,Z是表示GameObject在世界坐标系下的xyz坐标值,本例中的GameObject的位置确定是在Game视图下,实际观看GameObject的位置来手动调整的
      • c9e0fdb8e97d:你在什么平台上开发的?
        c9e0fdb8e97d:@Zui 我也是mac下运行,请问游戏运行的时候怎么不会动?我跑在真机上的
        c9e0fdb8e97d:@MandT 我也是mac下运行,请问游戏运行的时候怎么不会动?我跑在真机上的
        Zui:@MandT Mac下使用Unity开发
      • 张自:很棒
        Zui:@zaky 谢谢 :smile:

      本文标题:Unity官方实例教程 Space Shooter(二)

      本文链接:https://www.haomeiwen.com/subject/dtpchttx.html