初识Unity(十步做好你的第一个unity小游戏)_unity游戏开发步骤-程序员宅基地

技术标签: unity  

一、unity的整体认识

1、创建项目工程文件以及unity布局介绍

(1)打开unityhub,新建项目工程(Project)选择保存路径。

(2)unity的多种布局(窗口的排列)。

认识了tall布局下各个view的功能,四个开发视图(Scene,Project,Hierarchy,Inspector)以及一个game视图。

Scene(场景)视图:显示你当前的场景有哪些可操作的游戏物体,也就是你开发该场景的界面。

Project(资源)视图:存放你要用到的资源,包括音乐、材质、场景等等你要用到的资源。

Hierarchy(层级)视图:列出当前场景包含了哪些东西(把这些东西称为游戏物体)。

Inspector(检视)视图:显示我们所选择东西的属性的。

game(预览)视图:预览你的游戏运行。

2、场景、游戏物体和组件的概念和关系。

场景->游戏物体->组件

场景:一个游戏至少由一个场景组成,游戏很大的话分场景去做结构就可以变清晰。

游戏物体:当你打开一个场景就可以看到这个场景有哪些游戏物体,在Hierarchy视图或Scene视图中,你可以创建、删除、修改当前场景的游戏物体。(经常用到的快捷键需掌握:del删除、F2重命名等等)

组件:选中物体后在Inspector视图上会显示该物体所包含的组件以及各个组件拥有的属性。

场景由游戏物体组成,游戏物体由组件组成,组件包含了属性。通过写脚本和代码来控制不同组件的属性改变,来达到目的。

3、unity中的基本模型和场景操作。

我们在做游戏时会用到很多角色以及其它物体的模型,这时候一般就需要美工在其他软件上做出来我们使用。当然unity也有很多自带的基本模型可供我们使用,在Hirerachy视图中右键便可直接添加各种模型。

 创建一个模型后,便会在左侧Scene视图中显示。

场景的观察方式:Persp(近大远小)透视视野、Iso(长度相同)平行视野。

ISO和Persp操作方式有点不同,我习惯用ISO。 

接下来你就可以对他进行操作:

双击他的名称或者选中该模型按F:聚焦 

鼠标滚轮滑动:放大或缩小界面

鼠标中键:平移视图

鼠标右键:围绕物体旋转视角

4、unity中的坐标系。

3d游戏我们用直角坐标来确定物体在场景中的位置,我们可以在组件Transform的Position属性中修改物体的坐标。

当把一个物体拖动到另一个物体下面,该物体的坐标便是以另一个物体为原点。

世界坐标:相对于整个世界的中心点的坐标。

局部坐标:相对于上一级物体的坐标。

Transform右边有个设置按钮里面的Reset表示初始化。

5、unity中对游戏物体的常用操作。

Q工具:小拖手=鼠标中键

移动Position:W工具

旋转Rotation:E工具

改变大小(长宽高)Scale:R工具

———————————————————————————————————————————

对于unity的各个部分的功能以及操作,我们不必像字典内容一样一一背下来,我们只需要从做一些小项目开始,当你遇到一个知识点,就去了解一个,遇到一个就想方设法吃透它,因为你做的项目需要你用这个知识点,才能继续下去,这样子比你之前去背,要有趣和你对它的熟悉程度要大得多。

下面我们通过一个简单的小游戏制作,了解unity基础操作功能,同时收获一点成就感。

二、第一个游戏:Roll A ball。

1、Roll A Ball游戏介绍。

首先我们要做一个游戏,就要先清楚他的游戏的核心形式,以及游戏场景。在roll a ball 这个游戏中,我们的核心形式就是:要通过控制小球滚动来吃到所有的“食物”。游戏场景是一个有界的平台。所以我们要先创建出我们的场景和操作对象,再通过脚本来实现他们之间的操作。

2、初始化游戏环境。

(1)创建工程文件

        创建一个工程命名为Roll A Ball,选择3D。

(2)创建游戏场地(地面)和角色(小球)

        创建一个场景,放在Project视图里的Scenes文件下,再在Hierarchy视图里右键选择 3D Object创建地面(Plane)和小球(Sphere),按下F2可以重命名。

        初始化小球和地面的坐标,使小球在地面上。   但我们发现小球有一点陷入,使用W工具改变小球y坐标使小球在地面上方。

      

 根据自己想要的大小,可以更改小球或者地面的Scale达到合适的大小。我们也可以通过Material来改变场地的材质。

 如:把添加的Material中的color属性换个颜色,然后把Material拖到Scene视图中的地面上,地面的颜色就会改变。

3、刚体介绍和脚本的创建。

(1)刚体组件的介绍

        刚体组件可以让物体拥有重力,选中物体后在右侧Inspector视图下方添加Rigidbody组件,点击运行,物体就会从高处落下。

(2)脚本的创建

        我们现在就可以通过写脚本来控制刚体组件的属性来控制小球的移动,下面我们先学习脚本的创建。

在Project视图中新建一个文件夹Script来存放脚本,如图中右键选择C# Script,然后把它添加到小球的组件中。

 选中小球(图中的player),把下方新建的脚本拖入右侧,现在我们就给小球创建了一个空的脚本了。

4、通过代码控制移动以及如何通过键盘控制小球移动。

(1)通过代码控制小球移动。

双击Project中要编写的脚本,自动打开编写代码环境,我这里是vs2019。

这里一共由三行代码实现小球的运动。

private Rigidbody rd;        //定义一个rd来接收物体的刚体属性;

rd=GetComponent<Rigiidbody>();       //把物体的刚体属性赋值给rd;

rd.AddForce(new Vector3(1,0,0));       //引用rd中的一个AddForce方法给指定向量上一个力;

这样我们就可以利用刚体给小球一个x方向上大小为1的力了,更改new Victor3向量的方向即可更改小球运动方向。

(2)通过键盘控制小球移动。

既然通过给小球一个方向上施加力可以让小球移动,那么我们就在玩家输入wsad时分别朝四个方向施加力,来达到小球方向改变的目的。

———————————————————————————————————————————

我们先了解几行代码:

unity中Input.GetAxis()的用法

       float x= Input.GetAxis("Horizontal");                //对应键盘上的A键和D键 或←键和→键
       float z = Input.GetAxis("Vertical");                 //对应键盘上的W键和S键 或↑键和↓键
       float h = Input.GetAxis("Mouse X");          //对应X方向上鼠标的移动,在移动设备上也可以这样
       float v = Input.GetAxis("Mouse Y");          //对应Y方向上鼠标的移动,在移动设备上也可以这样
       float m = Input.GetAxis("Fire1");                   //对应鼠标左键或left+Ctrl
       float n = Input.GetAxis("Fire2");                   //对应鼠标右键或left+Alt
       float k = Input.GetAxis("Fire3");                  //对应鼠标中键或left+shift
        float m1 = Input.GetAxisRaw("Fire1");
   input.getAxis()和input.getAxisRaw()的区别
        //input.getAxis()                返回值m从0渐变为1或者-1
        //input.getAxisRaw()         返回值从0变成1或者-1,没有渐变
   ——————————————————————————————————————————

所以我们在脚本中加入两行输入wsad时会返回值的代码,再用变量来接收,然后放入给小球作用力的向量中,这样当玩家按下wsad,就会在对应的方向给小球力,也就达到键盘输入控制小球运动的目的了。代码如下:

 float x= Input.GetAxis("Horizontal");           //对应键盘上的A键和D键 或←键和→键,返回值为小数
 float z = Input.GetAxis("Vertical");             //对应键盘上的W键和S键 或↑键和↓键,返回值为小数

原理就是在接受键盘上的a或←键时返回值从0开始渐变为-1,其他同理。

然后把接收的 h 和 v 放到new Vector3()的 x 和 z 坐标轴上,注意别放错了。

但是我们有个问题,小球这样移动太慢了,我们可以给这个向量乘以一个整型变量来增大它的倍速,并且我们在开头定义一下这个变量,我们就可以在Inpector界面直接修改force的大小。

 

 这样我们就可以通过wsad或者方向键来控制小球任意移动了。

5、控制相机的跟随以及小球移动范围。

每做完一部分内容我们可以运行进行测试,这时我们发现了两个问题:一是小球滚动时镜头不会跟着移动,会滚出镜头外;二是小球会滚到场地外边儿去。

(1)控制相机的跟随

 相机在场景中也相当于一个游戏物体,如图右下方小框就是相机的界面,我们可以拖动相机,让画面照到我们想要的位置。然后我们再写个脚本,让相机与小球的相对距离保持不变,这样小球在移动的过程中,相机也跟着移动,我们就实现了相机的跟随了。

那为何不能把相机拖到小球下面,让相机以小球为原点,这样不是也可以保持距离不变,而且还更简单吗?

确实距离不变了,但是在小球滚动的时候,它的xyz轴也在不断改变方向,这是我们运行起来,相机就会是天旋地转的画面。所以我们只要保持距离不变的跟随,不需要画面跟着转。

 我们在main camera中写一个脚本follow来控制跟随:

主要有三行代码

public Transform playerTransfrom;//定义一个playerTransfrom来获得小球的Transfrom信息。

private Vector3 offset;//定义一个offest来存放相机和小球的相对位置。

offset=transform.position-playerTransform.position;//用offest记录小球和相机的初始相对位置。

transform.position=playerTransform.position+offset;//把小球改变后的位置加上相对距离赋值给相机,这样就是实现了,相机跟随小球一起运动。

直接访问transform,访问的是当前组件的transform(这里也就是相机的transform)。

(2)小球移动范围的控制

        想要控制小球的移动范围,也就是在地面四周加上墙。

        我们创建一个cube,然后通过R工具改变它的大小,再通过E工具改变它的方向,最后通过W工具移到它该去的地方。

6、如何创建可收集的食物以及食物的旋转。

(1)创建可收集的食物。

        可收集的食物的本质是,一个个游戏物体,只不过我们通过代码让它变得被触碰后就被摧毁,得分加一,这样就达到了可收集的目的。要实现被收集我们需要检测到碰撞,所以我们呢先把食物以及食物的状态创建好。

我们创建一个cube,然后把它变为想要的大小,然后用E工具旋转45°(在右侧可以直接输入坐标、旋转角度、大小的值)。

同时我们可以用Material改变一下它的颜色,操作如(二、2.(2))的改变地面颜色,忘了吧QAQ,没事我给你们截了一张图,你们看着应该可以想起。

先在下方创建个Material,再拖到物体上。0.0很简单吧。多复制几个让后放到不同的位置食物就创建好了。

(2)控制食物的旋转。

为了结构清晰我们可以创建一个空的游戏物体,然后把这些食物放到PickUps下面。

现在我们可以通过代码来控制食物旋转,但是我们这样要一个个的去修改,所以我们在这里通过修改标签,就可以达到全部修改的目的。

直接在标签里添加一个脚本控制食物旋转。

这里用到一行代码:transform.Rotate(new Vector3(0,1,0));  //意思是引用transform的Rotate功能绕(0,1,0)旋转。速度为1s60帧,后面我们也可以用代码控制。

运行后便可以达到旋转的目的了,下面我们再来看看碰撞。QAQ

7、碰撞检测。

碰撞检测:检测一个物体与另一个物体有没有发生碰撞。

我们是通过刚体组件中的一个OnCollisionEnter功能来检测的。(关于这些功能在unity手册中有,这些功能需要我们去熟悉。)

 我们在控制小球的脚本中写入OnCollisionEnter来获取碰撞目标的信息:

void OnCollisionEnter(Collision collision)   //接收碰撞到的游戏物体。

{

        string name=collision.collider.name; //collision.collider获得目标物体上的collider组件信息。

        print(name);输出碰到物体的名字到控制台。(在界面左下角)

所以我们可以通过碰撞检测来控制:如果碰撞目标的标签和食物标签一样,我们就摧毁它。

void OnCollisionEnter(Collision collision)

{

        if(collision.collider.tag=="PickUp")    //判断标签是否相等

        {

                Destroy(collision.collider.gameObject);//摧毁游戏物体

        }

}

8、小球通过触发检测吃掉食物。

当小球吃食物时会先发生碰撞,被弹起,食物再消失,这样不太好。食物应该直接消失不应该阻拦小球运动。所以我们在此用到触发检测。

 选中PickUp标签中Box collider的Is Trigger组件,意思是把碰撞器改成了触发器了。

 这时候小球就会穿过食物,但是不消除。因为用的是触发器,碰撞检测无法检测,我们要用触发检测才能够对应触发器的检测。我们现在把触发检测写到脚本中:

 void OnTriggerEnter(Collider collider)    //引用触发检测。

{        //如果触发到的物体标签是PickUp,那就摧毁该物体。

        if(collider.tag=="PickUp")

        {

                Destroy(collider.gameObject);

        }

}

碰撞会发生实际的物理效果,触发不会。

9、显示分数和胜利检测。

(1)得分显示。

我们是在触发检测中显示吃食物的,所以我们在触发检测中当检测到食物时我们就让得分加一。

声明一个score变量,在collider.tag=="PickUp"时score++。

我们再来看如何在界面上显示score。

在Hierarchy界面中添加一个UI->Text,也就是文本框。然后我们切换到2D模式。

 

左上角点击变为2D模式,然后选择Text点击右边红框然后按住alt点击左上角,这时你的这个文本框就到相机视图的左上角去了。

然后我们进行脚本的编写来控制分数的增加,在player脚本中定义一个text:public Text text。这时我们就可以在player中看到text组件,我们把创建的text拖到这里面,表示我们脚本要引用的text。

 然后我们就可以在脚本中对该text进行操作。

 这行代码表示,给这个text的text属性赋值为score的值。这时我们运行游戏,吃一个食物,score++,text显示的值也加一。

(2)胜利检测。

        在小球吃完食物的时候,我们就在屏幕中显示You Win! 添加文本框过后,可以在右侧对文字的颜色大小进行修改。 

我们想控制小球在吃完时才显示这个文本框,就可以先禁用右上角处的游戏物体是否启用,然后用代码控制在条件合适的时候启用。我们还是在需要用到什么的时候应该先定义:

 我们想对游戏物体进行修改的话,就是用GameObject定义;

只对其组件进行修改,就使用对应组件来定义。

然后我们一共有11个食物,所以当分数为11的时候,我们就激活启用按钮,就可以显示出来You Win!

10、游戏的发布和运行。

好啦,到现在我们就成功做出来了一个简单的小球吃食物的游戏了。接下来我们就把它发布出来,并且成功运行。

在file中点击Build setting。 

选择发布的平台,一般是选的PC端,其他的后面再学。

然后我们选择build然后选择一个文件夹保存。

这样我们就保存到桌面了,这里会有两个文件,一个是数据文件,一个是应用程序缺一不可。

我们直接点exe文件运行游戏。

现在就可以玩你自己做的第一个游戏啦。 

但是这个游戏有个小bug,如果你没选窗口模式,那么你就是全屏无法退出游戏,只有强行结束QAQ。。。

好啦到这里就结束了,初识unity,自己学到了很多,分享给大家,大家是不是也对unity有一些兴趣了呢。

以后会多多分享自己的unity学习经历,希望各位大佬多多指教QAQ。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Adamwen520/article/details/125546989

智能推荐

EasyDarwin开源流媒体云平台之EasyRMS录播服务器功能设计_开源录播系统-程序员宅基地

文章浏览阅读3.6k次。需求背景EasyDarwin开发团队维护EasyDarwin开源流媒体服务器也已经很多年了,之前也陆陆续续尝试过很多种服务端录像的方案,有:在EasyDarwin中直接解析收到的RTP包,重新组包录像;也有:在EasyDarwin中新增一个RecordModule,再以RTSPClient的方式请求127.0.0.1自己的直播流录像,但这些始终都没有成气候;我们的想法是能够让整套EasyDarwin_开源录播系统

oracle Plsql 执行update或者delete时卡死问题解决办法_oracle delete update 锁表问题-程序员宅基地

文章浏览阅读1.1w次。今天碰到一个执行语句等了半天没有执行:delete table XXX where ......,但是在select 的时候没问题。后来发现是在执行select * from XXX for update 的时候没有commit,oracle将该记录锁住了。可以通过以下办法解决: 先查询锁定记录 Sql代码 SELECT s.sid, s.seri_oracle delete update 锁表问题

Xcode Undefined symbols 错误_xcode undefined symbols:-程序员宅基地

文章浏览阅读3.4k次。报错信息error:Undefined symbol: typeinfo for sdk::IConfigUndefined symbol: vtable for sdk::IConfig具体信息:Undefined symbols for architecture x86_64: "typeinfo for sdk::IConfig", referenced from: typeinfo for sdk::ConfigImpl in sdk.a(config_impl.o) _xcode undefined symbols:

项目05(Mysql升级07Mysql5.7.32升级到Mysql8.0.22)_mysql8.0.26 升级32-程序员宅基地

文章浏览阅读249次。背景《承接上文,项目05(Mysql升级06Mysql5.6.51升级到Mysql5.7.32)》,写在前面需要(考虑)检查和测试的层面很多,不限于以下内容。参考文档https://dev.mysql.com/doc/refman/8.0/en/upgrade-prerequisites.htmllink推荐阅读以上链接,因为对应以下问题,有详细的建议。官方文档:不得存在以下问题:0.不得有使用过时数据类型或功能的表。不支持就地升级到MySQL 8.0,如果表包含在预5.6.4格_mysql8.0.26 升级32

高通编译8155源码环境搭建_高通8155 qnx 源码-程序员宅基地

文章浏览阅读3.7k次。一.安装基本环境工具:1.安装git工具sudo apt install wget g++ git2.检查并安装java等环境工具2.1、执行下面安装命令#!/bin/bashsudoapt-get-yinstall--upgraderarunrarsudoapt-get-yinstall--upgradepython-pippython3-pip#aliyunsudoapt-get-yinstall--upgradeopenjdk..._高通8155 qnx 源码

firebase 与谷歌_Firebase的好与不好-程序员宅基地

文章浏览阅读461次。firebase 与谷歌 大多数开发人员都听说过Google的Firebase产品。 这就是Google所说的“ 移动平台,可帮助您快速开发高质量的应用程序并发展业务。 ”。 它基本上是大多数开发人员在构建应用程序时所需的一组工具。 在本文中,我将介绍这些工具,并指出您选择使用Firebase时需要了解的所有内容。 在开始之前,我需要说的是,我不会详细介绍Firebase提供的所有工具。 我..._firsebase 与 google

随便推点

k8s挂载目录_kubernetes(k8s)的pod使用统一的配置文件configmap挂载-程序员宅基地

文章浏览阅读1.2k次。在容器化应用中,每个环境都要独立的打一个镜像再给镜像一个特有的tag,这很麻烦,这就要用到k8s原生的配置中心configMap就是用解决这个问题的。使用configMap部署应用。这里使用nginx来做示例,简单粗暴。直接用vim常见nginx的配置文件,用命令导入进去kubectl create cm nginx.conf --from-file=/home/nginx.conf然后查看kub..._pod mount目录会自动创建吗

java计算机毕业设计springcloud+vue基于微服务的分布式新生报到系统_关于spring cloud的参考文献有啥-程序员宅基地

文章浏览阅读169次。随着互联网技术的发发展,计算机技术广泛应用在人们的生活中,逐渐成为日常工作、生活不可或缺的工具,高校各种管理系统层出不穷。高校作为学习知识和技术的高等学府,信息技术更加的成熟,为新生报到管理开发必要的系统,能够有效的提升管理效率。一直以来,新生报到一直没有进行系统化的管理,学生无法准确查询学院信息,高校也无法记录新生报名情况,由此提出开发基于微服务的分布式新生报到系统,管理报名信息,学生可以在线查询报名状态,节省时间,提高效率。_关于spring cloud的参考文献有啥

VB.net学习笔记(十五)继承与多接口练习_vb.net 继承多个接口-程序员宅基地

文章浏览阅读3.2k次。Public MustInherit Class Contact '只能作基类且不能实例化 Private mID As Guid = Guid.NewGuid Private mName As String Public Property ID() As Guid Get Return mID End Get_vb.net 继承多个接口

【Nexus3】使用-Nexus3批量上传jar包 artifact upload_nexus3 批量上传jar包 java代码-程序员宅基地

文章浏览阅读1.7k次。1.美图# 2.概述因为要上传我的所有仓库的包,希望nexus中已有的包,我不覆盖,没有的添加。所以想批量上传jar。3.方案1-脚本批量上传PS:nexus3.x版本只能通过脚本上传3.1 批量放入jar在mac目录下,新建一个文件夹repo,批量放入我们需要的本地库文件夹,并对文件夹授权(base) lcc@lcc nexus-3.22.0-02$ mkdir repo2..._nexus3 批量上传jar包 java代码

关于去隔行的一些概念_mipi去隔行-程序员宅基地

文章浏览阅读6.6k次,点赞6次,收藏30次。本文转自http://blog.csdn.net/charleslei/article/details/486519531、什么是场在介绍Deinterlacer去隔行处理的方法之前,我们有必要提一下关于交错场和去隔行处理的基本知识。那么什么是场呢,场存在于隔行扫描记录的视频中,隔行扫描视频的每帧画面均包含两个场,每一个场又分别含有该帧画面的奇数行扫描线或偶数行扫描线信息,_mipi去隔行

ABAP自定义Search help_abap 自定义 search help-程序员宅基地

文章浏览阅读1.7k次。DATA L_ENDDA TYPE SY-DATUM. IF P_DATE IS INITIAL. CONCATENATE SY-DATUM(4) '1231' INTO L_ENDDA. ELSE. CONCATENATE P_DATE(4) '1231' INTO L_ENDDA. ENDIF. DATA: LV_RESET(1) TY_abap 自定义 search help