Unity官方实例教程 Roll-a-Ball(二)

作者: Zui | 来源:发表于2015-10-27 20:39 被阅读18388次
    Roll-a-Ball 游戏

    前言

    Unity官方实例教程 Roll-a-Ball(一)中,我们学会了:

    • 新建一个Project
    • 新建一个GameObject
    • 创建了一个球体
    • 给球体添加了刚体(Rigidbody)和脚本(Sprite),让我们可以通过方向键来控制球体的移动

    如果运行过游戏的朋友就会发现一个问题,虽然我们可以控制球体运动了,但是游戏视角好像不会随着球体而移动,球体一下子就会跑到摄像机看不到的地方去了,那么这一节我们就会学习以下内容

    你将学到什么?

    • 如何让摄像机跟随球体移动
    • 制作围墙来防止球体跑出平台
    • 添加一个自带旋转动画的方块
    • 制作一个Prefab和使用Global模式
    • 让球体可以拾取方块
    • 制作一个计分板来显示分数
    • 发布游戏到网页上

    一、让摄像头跟随球体移动

    首先我们选中我们的摄像头(Main Camera),然后我们会看到如下的情况:

    摄像头视角
    在上图中,我们可以看到,在Scene窗口的右下角,也就是图中红框处,有一个小窗口,这个窗口就显示我们此时选中的摄像机所有看到的内容,方便我们调整摄像机的位置,所以我们先拖动摄像机的位置和角度,来处于一个合适的视角,本例中,我们将摄像头的Position的Y和Z分别调至5和-6,然后把其的Rotation的X值调至45,这样摄像机的视角就变成了45°俯视角
    45°俯视角

    视角调整好后,我们接下来要让摄像头跟随球体来移动,我们第一个想到的办法,也是最简单的方法,就是把摄像机变成球体的一个子对象,这样球体移动,摄像机也会跟着变化,好,我们马上做做看


    将摄像机变为球体的子对象

    然后我运行游戏,看看能否达到我们的效果


    天旋地转

    天了噜,我们发现摄像头的确是跟着球体移动了,但是它不止位置跟着球体变化,他的角度也会跟着球体变化,这样摄像头就会出现天旋地转的效果,这不是我们想要的效果

    Tips: Unity中,子对象的Transform属性会跟随父对象一起进行变化

    我们想要的效果只需要摄像机的位置跟随球体移动,角度不需要,所以我们只能用脚本来实现这一效果,首先我们给摄像机添加一个脚本(大家应该还记得如何添加吧,不记得可以回去看第一节的内容,这里就不再重复介绍了),我们给脚本命名为CameraController,脚本语言选择C#。然后我们看看脚本内容:

    脚本内容
    我们一句句来解读脚本的含义:
    • 首先,我们定义了一个public的GameObject变量,这个变量就是用来告诉程序,摄像机会跟随哪个GameObject来移动
    • 然后我们定义一个private的Vector3的变量,这个变量我们主要用来记录摄像机初始的位置,用作之后更新摄像机的位置的偏移向量
    • 然后我们在Start方法中,摄像机的position数值赋给offset变量,意思是在开始前,用offset变量记录下摄像机的初始位置
    • 最后我们在LateUpdate方法中,把摄像机的位置变更为球体的位置加上最开始的偏移位置

    这里其实脚本中使用Update方法一样可以达到效果,但是我们使用LateUpdate(最后更新)效率会更高一点

    写完脚本内容后,我们保存一下脚本,然后回到Unity编辑器界面,我们会发现摄像机的脚本组件中,多了一个Player属性,如下图:


    Player属性

    这就是我们刚刚在脚本中定义的public类型的属性

    Tips: 在Unity脚本中,public的属性会在编辑器中显示出来

    然后我把把球体拖入到Player属性中,如下图:


    球体拖入到Player

    接下来我们运行一下游戏,就可以发现摄像机现在可以正常跟随球体移动了

    二、制作围墙防止球体跑出平台

    摄像机可以跟随球体移动后,我们又看到一个问题,球体如果移动超过平台的边界,就会掉下去,这不太友好,所以我们接下来给平台加上一圈围墙,来防止球体跑出平台

    我们新建一个cube对象,然后reset他的Transform属性会发现cube和球体挡住到了一起,这样不方便我们来编辑cube

    被球体挡住的cube

    为了方便编辑cube,我们可以暂时不显示球体,我们选中球体,将球体的Inspector下方的勾选去掉,如下图:

    去掉球体的勾选

    这样一来,球体就展示在我们的Scene窗口中不显示了。接下来我们可以编辑cube的属性,将其的长度设置成和平台一样,然后将其的位置移动到平台北面的边缘,如下图:


    北面的墙面

    然后同样的,我们给平台的南面,西面,东面都制作一堵墙,如下图:

    四面墙

    然后在运行一下,可以看到球体就没法跑出平台了

    三、添加一个旋转的方块

    有了平台,有了球体,接下来我们就需要一个方块,这个方块可以让球体碰撞并拾取,为了让方块变得有吸引力一点,我们让方块可以自动旋转起来,首先我们创建一个cube对象(不要忘记创建GameObject之后的两个标准动作),然后我们将cube命名为PickUp,并把它的Rotation的X、Y、Z值都设置为45,然后将其拖动到一个你觉得合适的位置,比如这样:


    EBCA8672-D12F-43CB-8BAE-1515CE33A542.png

    之后我们给这个方块添加一个自动旋转的脚本,脚本名称为Rotator,脚本内容如下:

    脚本内容

    里面我们就添加了一句话,就是红线标记的,Time.deltaTime就是根据时间变化来改变方块的Rotation属性,从而达到旋转的效果,保存脚本,然后运行一下,就可以看到方块自己旋转起来了。

    四、制作一个Prefab和使用Global模式

    为了让游戏丰富起来,我们只有一个方块是不够的,因此我们需要多创建几个方块,在这之前呢,我们需要先制作一个Prefab(预制件),制作一个预制件有以下好处:

    • 一次制作,重复使用:可以在任何项目中使用Prefab
    • 一次修改,全部变化:我们修改Prefab的属性后,所有使用该Prefab的对象属性都会跟着发生变化
      而制作Prefab的方法也非常简单,我们为了资源管理方便,先在Assets文件夹下面创建一个Prefabs文件夹来存放Prefab文件,然后拖动Pickup对象到Prefabs,一个Prefab就创建好了
    创建Prefab 创建好的Prefab文件

    然后我们可以复制PickUp对象,并拖拽新的PickUp到合适的位置,此时你会发现拖拽没有办法保持Y轴不变,因此为了方便我们移动PickUp对象的位置,我们先将Scene视图改为Y轴模式


    Y轴模式

    然后将Local模式改为Global模式


    Global模式

    此时我们便可以方便的调整PickUp对象的位置了,最后效果如下:


    C308023F-DF15-4553-9EB9-54D542871813.png

    从图中我们可以看到,一共拥有8个PickUp方块。

    五、让球体拾取方块

    接下来我们实现球体拾取方块的功能,我们通过查API得知有一个OnTriggerEnter的方法可以用来在球体碰到物体的时候调用,光有这个方法还不够,我们还需判断球体碰到的是什么东西,我们不能碰到任何东西都拾取,所以我们需要给拾取的方块增加一个标记(Tag),增加标记的方法如下:

    • 因为我们场景里面一共有8个方块,如果一个个的设置标记,就有点太麻烦了,还记得上面我们提到的Prefab的第2点好处吗?对了,这边我只需要给Prefab标记就可以了

    • 首先我们选中PickUp Prefab,然后在Inspector的Tag里面新增一个Tag,我们命名为PickUp

      New Tag
      Add Tag
    • 然后我将PickUp Prefab的Tag设置为“PickUp”

    接下来我们就可以进行脚本编写了,我们打开球体的PlayerController脚本,然后新增下面的代码

    代码
    首先这里other变量代表球体碰到的对象,在这个方法里面,我先用if语句判断碰到的对象的Tag是否等于“PickUp”,如果等于,我就将碰到的对象设置为不激活(不显示)

    做完这些,我们就可以运行一下游戏,看看效果
    …………
    …………
    …………
    咳咳,我们运行了游戏发现,球体碰撞方块并没有将它拾取,这是为什么呢?原因是我们没有将方块设置为碰撞触发器(Is Trigger),只有设置成碰撞触发器,我们才可以的OnTriggerEnter方法才能起效果,我们设置成后,再运行游戏,可以发现,现在球体碰到方块就可以拾取了

    六、制作一个计分板

    好了,我们的游戏基本可以玩了,但是我们还需给玩家增加一点刺激,做一个计分板来鼓励玩家多拾取方块,那么实现一个计分板我们需要以下元素

    • 用一个变量保存玩家的分数
    • 然后将分数显示在UI上面

    首先我们修改PlayerController脚本,如下:

    BE1A3ECF-A8DF-49CD-9FD0-63BF90E6EED4.png
    上图第一句红线处,我们定义了一个count变量用来保存分数,然后在Start方法中将Count的值设置为0,即我们在游戏开始时,将分数初始化为0,最后我们在拾取方块的时候,把count的数量加1

    这里count++是一种简写,其实它的效果等同于**count = count + 1

    现在我们有了变量来记录分数,但是我们还没有显示给玩家,所以我们需要一个UI来显示分数,我们创建一个文本UI(Text UI)


    Text

    然后我们调整Text的位置至屏幕的左上角


    3966D5E5-6A9E-429E-91A1-D2B1B5E0C2F3.png

    接下来我们再次修改PlayerController,如下:

    21A49D5B-9E81-4D8A-AE78-99F1A74B5B7C.png
    • 在代码最前面,我们需要引入UnityEngine.UI,只有这样后面代码才会识别Text类型的变量,
    • 然后我们在定义countText变量来保存UI Text
    • 接着我们在Start方法中调用setCountText方法,来更新countText的内容
    • 然后我们在每次球体碰到方块的时候,也需要更新countText的内容
    • 最后是我们定义的setCountText方法

    然后我们保存代码,回到Unity编辑器里面,将Text拖入到Player里面的Count Text属性


    D13B9B82-26DB-481F-87D5-E934BA785D4A.png

    做完这些,我们就可以运行游戏,看到效果了!

    七、发布游戏

    游戏到这里我们就告一段落了,接来下我们可以尝试将游戏发布到网页,让你的朋友试玩你的游戏,Unity发布游戏非常简单

    • 第1步:首先选择File->Build Settings

    • 第2步:我们选择Web Player平台,然后点击Switch Platform

      屏幕快照 2015-10-27 下午8.33.55.png
    • 第3步:我们点击Add Current按钮,将当前游戏场景加入进去

    • 第4步:点击Build按钮,然后选择保存路径,就可以完成发布了

    最后我们找到保存路径下生成的文件,点击后缀为html的文件,就可以运行游戏了


    A36355F0-C4B5-4774-973B-4D363180F848.png

    相关文章

      网友评论

      • 228dc8120c5c:这个问题困扰我一天了,后面发现作者写的太粗糙。给后来人提醒吧。按照教程吧MainCarmer放入play目录下,运行CameraControl脚本,还是会天旋地转!解决方法:MainCarmer不要移动到paly目录下 直接编写脚本就行了!如果是我理解错误欢迎交流!谢谢!
        melith:作者说了,移动到play目录下是不可以的,会天旋地转,这只是举一个反面例子,告诫我们不要这么做,这么做是不行的。
      • QianqianLis:在unity里面碰撞拾取功能正常,build之后,小球就会穿透方块。。。。
        QianqianLis:@treegrow unity是免费版吗?用破解版就好了
        45c442f27896:我也是,怎么回事呢
      • c7dec712c898:为什么我在unity里面功能正常,build成exe之后,小球就会穿透方块呢
        45c442f27896:我也是,怎么回事呢
      • a51228bead58:没有Web Player??
        4cbc74486dc4:5.4版本以后就没有web player了,都是webgl发布。如果发布不成功的话,unity会自动有提示下载插件。
        小巷里有只猫:这个好像unity取消掉了
      • tidus5:补充几点,也是自己在看这篇教程的时候有点不清楚的地方。
        其实结合官方视频,就可以更清晰的了解了。
        四个边界的做法,其实位置可以拖动箭头来摆放,但准确的还是用坐标。
        做法是,定义一个 空的Wall 的GameObject,当做文件夹。
        第一个方块,命名为West Wall,Position 填-10, 0, 0 Scale 填0.5, 2, 20.5
        然后复制,操作为点击Edit 菜单,选择 Duplicate, 快捷键是 Ctrl+D
        将复制出来的 West Wall 1 改名为 East Wall ,然后只需要Position 的 x 改为10
        再复制一个,改名为North Wall,把x Position 设为0,
        这里有两种方法变换,一个是旋转,设置 Rotation 的Y 为90,方块就横过来了
        还有一个方法就是变换大小,设置Scale为 20.5,0, 0.5 Position 填 0, 0, 10
        然后再复制 North Wall,命名为 South Wall, 然后Position 的 z 改为-10
        就可以了
        tidus5:同时注意,新建GameObject 后,Reset 坐标的重要性。
        我这里方块就算 Y 设置为 0.5 都全部飘在球上方,够不着,找半天原因,原来是 PickUp 的文件夹没有Reset 坐标,导致下面的子元素都跟着坐标偏移了, 把那个父节点 Reset 就好了
        tidus5:然后,那几个小方块,官方给的大小,Scale 是 0.5 , 0.5 0.5
        设置Rotation 都是 45度, 添加到Prefeb, 添加脚本 之后,用 Ctrl+D 复制,
        然后因为拖动时,xyz 三个坐标可能都在变,Y坐标改了之后,可能方块高于平面,或者陷入平面。 所以切换到Y轴,从上往下看。
        然后切换到Global。 这里是让坐标都改用世界坐标。
        而不是每个方块的自以为的上下左右,因为旋转而变得 斜45度角的三维坐标轴。
        世界坐标就不管你方块转的角度,不管方块自己觉得的上下左右,而以整个世界的东西南北上下
        然后,鼠标拖动方块移动的时候,要注意!!! 点住 红蓝坐标轴中间的绿色方块再拖动。
        这样的拖动才是 Y 不变的,如果点的不准确,Y可能还是会变的!!

        另外,平面白色的底色,在拖方块的时候很难看清,其实官方教程平面是蓝色的,这里省去了。
        平面变蓝的方法是,Project 里面建立 Materials 的文件夹,存放材质,然后里面新建一个Material 命名为 Background, 在右边的Inspector 的 Main Maps 的第一项 Albedo 是设置材质反射的颜色, 点开后出来调色板,可以点击下面数值框上面的小的花花绿绿的按钮,切换定义方式,切换为 RGBA 表示法后,设置RGB 为 0, 32, 64, A 为255, 下面可以看到预览。
        然后从Project 里,把Background 材质直接拖动到平面上就可以给Plane 换上了。

        这样基本做出来的效果和官方就差不多啦!! B站有上传官方视频,没FQ得可以去照着操作
      • DO_3892:Java程序员,刚开始学unity,非常感谢
      • 47241299394d:GameObject→UI→Text,创建出的UI在场景中,并且包括在画布“Canvas”中,拖动Text到差不多的位置,开始游戏后更不看不到啊。。。求大牛帮助。 /(ㄒoㄒ)/~~
        47241299394d:@一只米 对,text在场景中的canvas画布上直接拖动
        一只米:@某人_4a6f 请问 是直接在当前canvas被锁定的情况下,把text拖动到 想要的位置就行了么
        47241299394d:搞定了,当添加一个 UI → Text 后,在"Hierarch"窗口中自动添加了一个Canvas,这个Canvas(画布)有三种用法,默认的就是Screen Space - Overlay:作用为屏幕最上层,你窗口有多大,这个Canvas就有多大,被锁定无法改变大小(换句话说,这个画布就是你的窗口),主要是2D效果。这个效果需要在2D状态下调整,把Text项拖动到你想要的位置就好了。
      • 1f8f43944e4f:碰撞触发器在哪里进行设置呢
        47241299394d:@七月kirino 是给方块添加啊
        4d09a25c6d9c:@某人_4a6f 为什么是球体不是方块呀
        47241299394d:Inspector → Sphere Collider → Is Trigger
      • ad02ce1db638:我的球不能拾取方块,为什么呢
        fb4a9f710537:Rotator脚本应该写在“刚体脚本”里面,并且将PickUp的Is Trigger "打勾".
        ad02ce1db638:@Cooper_Leung 对啊对啊,前两天看视频才看到。晕死了
        571de4da5910:tag是不是没有选中pickup
      • 唯爱伊人醉:对于初学者入门来说,这份教程真的很好,真心感谢!!!!
      • d6b5f41a03de:学习了
      • 74386c2df909:setCountText出错
      • 1451c55ba686:感谢,按照步骤顺利的弄出来了
        嘿_670c:为什么我的球会自动穿过ground
      • ef5d946f6806:这一个学过
      • 银狐游戏开发资源:很不错,请问作者可否提供更多的教程?我看了就二个,还有一个飞机的
        请问如何联系作者?
        我是夜晚:搜space shooter
      • 11af599fbe12:您好,CameraController里面的offset变量定义是不是错了?
        45c442f27896:没错,我刚试的,OK
      • 记录卡:谢谢您的教程
      • 96f0b1bf95dc:Unity 已经不再支持web player了,以后作者得换其他的发布方式写文章了。。。
      • e7fe1d899d33:按耐住要打赏的强烈冲动,亲自写下对作者的祝福:初学者感谢有你!

      本文标题:Unity官方实例教程 Roll-a-Ball(二)

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