转载:https://blogs.littlegenius.xin/2019/02/10/从滚球游戏初步体验Unity3D/

从创建项目开始

创建一个项目

打开unity,在Projects中可以查看当前的本地项目或者云端项目,点击New project或者右上角的New都可以新建项目。

然后在1处填写创建项目的名称,2处选择创建地址,3处选择Template(模板),可以选中3D或者2D。


稍等片刻即可进入unity的主页面。

保存Scene并管理Assets

进入unity之后,可以看到已经预设的SampleScene和其中的Main Camera(主摄像机)和Directional Light(平行光)组件,如果你不喜欢这些预设的名字,直接点击修改并使用Ctrl+S保存你的修改即可。

为了使我们的Assets文件夹管理地更加井井有条,推荐对不同的assets进行分文件夹管理,这时一些文件夹的命名可以自己定义,但通常可以遵循一定的不成文的规定,比如通常将场景存放在Scenes目录、将脚本存放在Scripts目录等等,要根据自己来管理好Assets目录,以后对于大量的assets可以很方便快捷。

创建游戏场景

创建Plane

可以使用unity的内置GameObject的Plane(平面)类型来作为游戏场景的“地面”。
可以在Hierarchy视窗下右键选择3D Object下找到Plane创建,也可以在顶部菜单栏的GameObject下的3D Object下找到Plane创建。当然也可以看到unity为我们创建了很多预置的Game Object,比如3DO bject、2D Object、Effects、Light、Audio、 Video、UI、Camera等等,当然每一个分类下还有更详细的分类,这些都可以直接拿来使用,非常方便,一些重要的Game Object以后还会慢慢使用。

这里只需要创建一个Plane并将其命名为Ground来作为我们游戏的“地面”,可以看到Plane出现在了MainScene中,同时我们可以注意到Hierarchy视窗中的MainScene右上角出现了一个*号,这就表示该Scene处于待保存的状态,可以通过菜单栏的File->Save或者快捷键Ctrl+S保存Scene。


选中刚刚创建的Ground,Inspector视窗中就会出现其所有的Components,这些都是预先被untiy设置给Plane的,点击Transform这一Component的右侧的齿轮状图标,可以选择Reset(重置)选项,这样,刚刚创建的Plane的Transform就会被重置为初始值,它的Position会被设置为(0,0,0),这是整个游戏世界的原点坐标,游戏中的所有GameObject的坐标都是基于此原点进行计算的。


选中任何一个GameObject,比如选中Ground,然后按F键,或者在菜单栏中点击Edit->Frame Select可以快速地调整Scene的角度,让我们有一个非常合适的角度来观察Ground的全貌。

改变Transform

改变Transform的三组值的方法有很多。

直接赋值

可以在Inspector面板中对Transform的九个值直接输入数值来设置

拖动输入框调节

当我们把鼠标指向每一个值的输入框的左侧边界时,就会发现鼠标成为了一个左右双箭头的形状,此时按下鼠标左键所有拖动,就会发现该输入框变成了蓝色,并可以随着拖动改变它的值。

在Scene窗口中改变

在左上方有六个按钮,分别表示对Scene中GameObject的操作。
这里提一句:不管选中六个按钮中的哪一个,只要按住Alt键在Scene中拖动鼠标就可以转动视角,只要滚动鼠标滚轮即可放大/缩小视角。
这六个按钮从左到右依次为:

六个改变Scene中GameObject的选项

第一个:拖动Scene的视角
第二个:选中后,再选中Scene中的任何一个GameObject,就可以通过拖动它的三个方向箭头(x、y、z)以及三个平面(xy平面、xz平面、yz平面)来改变Position的值。

第三个:选中后可以在Scene中对选中的GameObject改变其Rotation的值

第四个:选中后在Scene中可以对选中的GameObject进行三个方向的Scale的调整

第五个:选中后可以在Scene中对选中的GameObject进行顶点的位置调整从而改变Scale的值

第六个:选中后可以同时改变Position、Rotation、Scale的值,是第二三四个的结合。

创建游戏对象

创建Sphere

接下来创建小球,同样地,在MainScene下右键->3D Object->Sphere来创建一个unity预置的Sphere(球体),命名为Player,并通过reset其Transform来使其位置重置到原点。

这样我们看到小球的中心已经被定位到了(0,0,0)处,为了让小球能在平面上滚动,我们需要将小球放到平面上。
观察小球的Transform我们可以得到,它的Scale的值为(1,1,1),也就是说它的三个方向的大小都为1单位,为了让小球放到平面上边,显然我们需要将其向上移动半个球的距离,即将Position的Y值设置为0.5,小球就刚好在平面上了。

关于光源

其实我们可以看到小球是有影子的,这是最开始unity为我们准备的Directional Light作用的结果,我们可以看到Scene中的一个小太阳的标志,这个就是我们的光源,使用Directional Light来模拟太阳的平行光。它的Transform则显示了光源的位置、角度(也就是平行光的照射方向),如果我们将这个GameObject去掉的话就没有了光的效果。
当然通过改变Rotation的值就可以调节光源的方向,比如为了效果我将Rotation的Y值改为60。

创建Material

为了使GameObject美观,我们通常会对其表面进行一系列装饰,而其表面的表现是通过为这个GameObject添加Material(材料)来实现的。
接下来为我们的Ground和Player添加最简单材料:纯颜色。
在Assets下新建Materials目录用于管理各种材料,然后右键该目录选择Create->Material新建一个材料命名为Background。

选中Background,就可以看到它的Inspector面板了,我们在Albedo(反射率)一栏中可以选择一种颜色,在下方的预览中就可以看到效果了,这里我们选择RGB色(0,32,64)作为我们的Background的颜色。

想要将创建的Material运用在某个GameObject上,很简单,只需要拖动该Material到Scene中的目标GameObject上或者拖动到Hierarchy的该GameObject上即可。

可以看到我们的Ground已经变成了蓝色

让小球滚动起来

让小球拥有成为刚体

为了让小球有滚动的效果,我们需要小球拥有一系列的物理属性,物理属性已经由unity内置,我们只需为需要增加物理属性的GameObject添加一个Rigidbody的Component即可。如上一节中所示,选中Player,在Inspector面板中通过Add Component中找到Physics下的Rigidbody即可。

为小球添加控制脚本

有了刚体属性的小球需要在我们的控制下滚动,比如我们规定使用W,S,A,D四个按键来控制小球的方向,那么对于一个有物理属性的刚体来说,为了能够动起来,当然需要力(Force)作用在物体上,这些有关于如何控制GameObject的方法需要我们使用脚本(Scripts)来完成,假如你已经拥有了一定的C#编程基础。
同样我们在Assets下创建Scripts目录来管理脚本,在该目录处右键->Create->C# Script创建一个脚本,这里我们命名为PlayerController。

为了让我们创建的脚本与Player联系起来,可以在Player的Inspector面板下选择Add Component,在其中搜索我们的脚本名字就可以找到该脚本,根据unity的命名规范,喜欢将脚本各个单词使用“驼峰法”并且首字母同样大写的方式,有趣的是,unity对于这些脚本通常都会在每个大写字母处将这些单词分开,我也不知道为什么。简单点儿的话可以直接将Assets中的脚本拖到Inspector面板下,就可以添加成功。

打开脚本

编辑脚本需要编辑器,Visual Studio是较好的选择,它和unity之间有很好的合作关系,使用起来也很方便。双击脚本文件或者在Inspector面板中点击脚本的右上角的齿轮图标选择Edit Scrpit都可以打开编辑器对其进行编辑。

unity已经为我们预置好了脚本的最基本结构,最基本的,我们可以看到所有的unity脚本都继承自MonoBehaviour类,然后有两个预设函数,Start函数是在第一帧开始渲染前调用,Update函数在每一帧刷新前调用,都是非常常用的函数。
接下来思考我们要做的事情,我们需要检测用户的输入,并且通过输入的按键来控制小球的滚动方向,检测用户的输入同时也需要识别输入的是哪一个按键,除此之外我们还需要一些物理学有关的逻辑,比如我们需要添加一个力来控制小球的移动,这就是物理学逻辑,这些逻辑当然是每一帧都要进行一次,所以我们需要将这些逻辑写在每一帧更新都要执行的函数中。
显然我们可以写到Update函数下,因为Update函数是每一帧刷新前都会调用的,同时我们还有另外的选择,即使用FixedUpdate函数,它在每一次进行物理学运算的时候调用,每次检测到用户输入都需要进行物理学运算,所以我们可以将逻辑写到FixedUpdate函数下。

开始编写脚本

首先我们需要创建一个对于这个Player小球的引用,这样才能知道我们控制的是哪个小球,这里小球是刚体,所以我们创建一个刚体(Rigidbody)的引用,并且需要在第一帧开始渲染之前通过GetComponent方法来找到小球创建刚体的引用,这一逻辑自然就需要写到Start函数中了。

private Rigidbody rigidbodyPlayer;void Start()
{rigidbodyPlayer = GetComponent<Rigidbody>();
}

接下来对用户输入的读取就需要写到FiexedUpdate函数中了,我们使用Input类的GetAxis方法来获取水平或者垂直的运动轴,这个方法会返回一个float值作为该轴的移动距离。

float moveHorizontal = Input.GetAxis("Horizontal");
float moveVertical = Input.GetAxis("Vertical");

通过以上两行代码我们就可以将用户的W,S,A,D输入转化为水平轴和垂直轴的移动距离,分别存储在moveHorizontal和moveVertical两个float类型的变量中。

接下来通过Rigidbody类的AddForce方法可以为刚体添加作用力,AddForce方法接受一个三维向量(Vector3)参数,这个三维向量就可以表示力,显然我们的三维向量可以用刚才的moveHorizontal和moveVertical两个变量作为X值和Z值,同时我们是不需要小球在Y方向上移动的,也就是将Y方向的力作用设置为0.0f即可,经过调试我们会发现小球的移动速度过慢,为了方便调节小球的速度,只需要在表示力的三维向量前乘以一个倍数即可,为了方便调整,我们设置一个public的float类型的变量speed来调节这个乘积。
这里必须说明的是,凡在unity的脚本中被声明为public类型的变量,在unity的Inspector界面中的该脚本的Component下都会出现一个可以设置的值的方框。

public float speed;
void FixedUpdate()
{Vector3 movement = new Vector3(moveHorizontal,0.0f,moveVertical);rigidbodyPlayer.AddForce(movement*speed);
}


此处我们将speed的值设为10比较合理,运行游戏就会发现通过W,S,A,D的控制,小球动了起来。

完整的代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class PlayerController : MonoBehaviour
{private Rigidbody rigidbodyPlayer;public float speed;void Start(){rigidbodyPlayer = GetComponent<Rigidbody>();}void FixedUpdate(){float moveHorizontal = Input.GetAxis("Horizontal");float moveVertical = Input.GetAxis("Vertical");Vector3 movement = new Vector3(moveHorizontal,0.0f,moveVertical);rigidbodyPlayer.AddForce(movement*speed);}
}

当然你也会发现,小球超出了Plane的边界居然掉了下去,其实这是合理的,因为小球为刚体,也就拥有物理引擎,当然受到重力的影响,在没有Plane的向上的作用力的情况下自然会下落。

设置摄像机

可以发现,我们的Camera的角度和位置都比较刁钻,这导致我们的游戏看到的画面并不完整,接下来我们对Camera进行设置,使其能够跟随我们的小球滚动来同时移动。
首先调节Main Camera的Position和Rotation使得画面和角度比较合适,比如这里将Position的Y值设为6,Z值设为-6,将Rotation的X值设为45得到了一个较为合适的位置。

接下来通过脚本控制Main Camera跟随小球Player一同移动,即在Position上保持相对静止。
可能你会想到,只需要将Main Camera拖动给Player使其成为Player的子物体不就可以保持两者相对位置不变化了吗?但是问题在于球体Player是滚动的,如果两者的位置完全相对静止,就会导致球滚动时Main Cmaera也会跟着球滚动,有一种天旋地转的感觉。感兴趣的话可以尝试一下。
新建脚本CameraController并添加给Main Camera做一个Component。为了使Main Camera的Transform的Position和Player的保持相对静止,Rotation并不和其保持一致,可以想到一个办法:设置一个偏移量,这个值初始化为游戏开始时Main Camera和Player之间的Position的差值,然后在球滚动时,每一次滚动都改变Main Cmaera的Position,使其新的Position等于现在球的Position的值加上刚才的偏移量,这样就会在每次球的位置改变时Main Camera都会跟上它的步骤。
显然,偏移量的设置需要在Start函数中完成,每一次球的位置发生变化时的逻辑可以在Update函数中完成,但还有一个更好的选择,就是LateUpdate函数,该函数在每次有GameObject发生变动时才会调用。
同时,我们的脚本使加在Main Camera上的,所以Main Camera的Transform可以直接调用,但是球的Transform则需要单独获取,这里我们设置一个public的GameObject量,然后在unity中将球Player拖动到这个量处作为参数即可。

private Vector3 offset;
public GameObject player;void Start()
{offset = transform.position - player.transform.position;
}void LateUpdate()
{transform.position = player.transform.position + offset;
}


这时候运行游戏就可以发现Main Camera的位置随着球的改变而发生了改变。

完整的代码:


using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class CameraController : MonoBehaviour
{private Vector3 offset;public GameObject player;void Start(){offset = transform.position - player.transform.position;}void LateUpdate(){transform.position = player.transform.position + offset;}
}

建立围墙

为了不让小球总是滚落到Plane之外,可以在其四周围建立起一圈儿围墙,很简单,使用预设的Cube就可以了。
为了更好的管理四个围墙,我们可以先创建一个空的GameObject,将其命名为Walls,Reset使其重置位置,然后在其上右键新建一个Cube,并命名为WestWall,这样这个Cube就成为了Walls的子物体。

接下来如何调整这面墙的大小、位置就很简单了,可以在Inspector中直接输入具体数值,也可以直接在Scene中拖动和缩放,最好我们可以得到这个墙体结构。

为了简单方便,只要选中WestWall,在菜单栏的Edit中选择Duplicate(复制)(快捷键:Ctrl+D)即可,然后将复制好的墙拖动到适合的地点,在复制,最后可以得到四面墙。

接下来测试游戏,墙起作用了!

创建碰撞小立方体

新建Cube

我们在游戏场地中加入一些旋转的小方块儿,然后由球来碰撞这些小方块儿,碰撞之后就加一定的分数。
很简单地,创建一个Cube,并命名为PickUp,使其Reset,然后我们调整一下它的Rotation和Scale,使得其变成一个斜放的小立方体,(为了方便看,这里暂时隐藏了Player,只要在Player的Inspector面板中将其前边的对勾打掉它就会隐藏)。

让小立方体旋转起来

为了让小方块儿更有趣,我们来添加一个脚本让他旋转起来,新建脚本Rotator,并添加给PickUp,编辑此脚本。
这个逻辑中是不需要Start函数的,我们只需要每一帧都让小方块儿转动一下,所以将逻辑写到Update函数中,这里使用Ratate方法,需要一个Vector3作为参数,为了不让旋转过快,我们给每一帧都乘以一个小的时间量。


private Vector3 rotation = new Vector3(15,30,45);void Update()
{transform.Rotate(rotation * Time.deltaTime);
}

保存脚本,运行游戏可以看到小方块旋转起来了。

创建Prefab

接下来我们需要多放置一些立方体在游戏的平面上,在此之前,我们需要把这个设计好的立方体生成一个Prefab(预设体),让它变成一个asset,这样我们可以从prefab创建这个立方体的实例,这样我们才能分别控制每一个由prefab生成的实例或者控制prefab本身,在这个游戏中,被小球碰撞到的小立方体会消失,这也就是我们需要更新每一个小立方体的状态,所以我们需要创建一个Prefab。

a prefab is an asset that contains a template, or blueprint of a game object or game object family.
(预设体是包含游戏对象或游戏对象族的模板或设计大纲的一种资源。)

在Assets下新建Prefabs目录来管理预设体,只需要将MainScene中的PickUp拖拽到新建的目录下就可以生成对应的asset了,这时也会看到MainScene中的PickUp变成了一个蓝色的图标。

此时在MainScene中新建一个空的GameObject来管理所有的小立方体,命名为PickUps,将刚刚的第一个PickUp拖拽到它的上边使其成为其子物体。

放置更多的立方体

接下来放置小立方体,为了调整一个好的视角,我们可以点击Scene中右上角的方位标志的Y轴的小锥体,就会调整视角到俯视的角度,这是一个便捷的小技巧。

由于我们的小立方体是一个斜放的立方体,在原本的坐标轴下很难调整立方体在水平面上的位置,这里还有一个小技巧,我们点击右上角的Local变成Global,这样就会在Global的坐标中对小立方体进行调整了,可以看到,小立方体的三个坐标轴变成了只有两个方向的轴,非常方便就可以调整了。

接下来只需要Duplicate几个或者使用Ctrl+D来重复放置一些小立方体即可。这里粗略地摆放了八个小立方体。

为小立方体涂色

让后再通过添加一种Material的方式将他们涂成黄色。
这里可以通过两种方式完成。
第一种,将Material拖拽给任意一个PickUp立方体,然后再该PickUp的Inspector的Prefab的Overrides(重载)下选择Apply All来让所有PickUp都被涂成黄色。


第二种方法会更加简单,直接将Material用于Assets中的小立方体的Prefab就可以啦,找到Assets中的PickUp的Prefab,点击Inspector面板中的Open Prefab,就会在Scene窗口中预览该Prefab,这是再拖动黄色的Material到他上边,这个Prefab就会被染成黄色了。


完成碰撞

为PickUp添加标签

如果小球碰撞了旋转的立方体,那么小立方体就会消失。那么如何识别我们的小球Player碰撞的是小立方体呢?我们通过为PickUp添加特定的标签来识别。添加标签再Prefab上,在Assets中找到我们的Prefab并打开它,可以在它的Inspector面板中发现它还没有添加标签(Untagged),点击Tag后的按钮选择Add Tag…,来添加一个名为PickUp的标签,然后再回到最开始的面板处选择新添加的这个标签,这样PickUp的标签就添加好了。

完成碰撞逻辑

重新编辑PlayerController的脚本,这里我们将碰撞发生的逻辑写到函数OnTriggerEnter中,这个函数在发生碰撞事件的时候调用,而且用碰到的Collider(碰撞机)作为参数,也就是我们的Player碰到的Collider。可见,如果要检测到的碰撞,被碰撞的物体需要由碰撞引擎,也就是要有Collider的属性,其实我们会发现,作为Cube保存的一个Prefab在创建之初就已经有Box Collider的这一Component了,所以不再需要我们自己添加。

OnTriggerEnter函数用其碰撞到的Collider作为参数,现在就需要我们识别这个碰到的Collider是不是一个PickUp了,显然可以使用Tag来鉴别,这里使用gameObject的CompareTag方法来完成,该方法以一个字符串作为参数,返回一个布尔值,如果gameObject的Tag和字符串一致,就返回true。
接下来完成控制小立方体消失的逻辑,很简单,使用gameObject的方法SetActive来完成,这个方法控制的就是我们在Inspector面板中看到的每一个GameObject前的小对勾,该方法接受一个布尔值作为参数来控制GameObject的消失与显现。
完整的代码如下:

void OnTriggerEnter(Collider other)
{if (other.gameObject.CompareTag("PickUp")){other.gameObject.SetActive(false);}
}

关于碰撞的简单原理

此时运行游戏,在小球碰到小立方体的时候小立方体并没有像我们像的那样消失,这里的原因需要我们了解一定的Unity对与碰撞到原理。Unity将Collider(碰撞机)分为静态碰撞机(Static Collider)和动态碰撞机(Dynamic Collider)两种。静态的碰撞机比如墙面、地板等一些列静态的物体,与他们碰撞时,不允许两个Collider相互重合,也就是说会发生反弹,而为了让我们的碰撞能够实现,我们需要将立方体设置为动态的(Trigger)触发器,成为Trigger的Collider是可以被穿过的,这样才会引发我们的“碰撞事件”的逻辑。这里我们找到PickUp的Prefab,在它的Box Collider的Component中,勾选Is Trigger选项,这样它就成为了一个触发器。

此时运行游戏可以发现,小立方体在受到碰撞后完美消失。

优化

这里有一个有关物理引擎的优化,首先我们区分了静态碰撞机和动态碰撞机,Untiy对于静态碰撞机,会将它们的体积记录在一个缓存中,这是很合理的,因为静态即不动,所以并不需要在每一帧都计算器和重新绘制它的体积,而动态的则不同,因为它是运动的,所以必须在每一帧处都计算和绘制,这个过程是需要耗费资源的。

Any game object with a collider and a rigid body is considered dynamic.
Any game object with a collider attached but no physics rigid body is expected to be static.
(任何同时带有Collider和Rigidbody属性的GameObject称为动态的,任何只有Collider而没有Rigidbody属性的GameObject称为静态的)

为了让PickUp成为动态的,这样不需要每一次都计算它的体积,我们为PickUp的Prefab添加Rigidbody属性,运行游戏,发现神奇的事情发生了,所有的PickUp居然掉了下去,这当然是由于所有的刚体都受到了重力的影响,所以PickUp会下落。


为了解决这一问题,移步到PickUp的Prefab下刚刚添加的Rigidbody属性处,会发现有两个选项,分别是Use Gravity和Is Kinematic。

显然,我们可以直接将Use Gravity的对勾打掉,这样它不再受重力,自然不会下落,这是一个解决办法,但是并不完美,因为这里我们只取消了重力,但对于一个刚体来说,还会受到其他的力从而使其改变Transform,所以更好的做法是选中下方的Is Kinematic选项,接下来解释Kinematic:
Kinematic Rigid body(运动刚体)的含义是它的Transform也就是位置、角度、大小不会随着力的作用而改变而是单纯地根据Transform设置的值来改变,也就是说我们不能通过对其作用力来改变它的Transfrom,改变的唯一方法是直接调节其Transform下的各个值。
运行游戏,完美!

添加计分机制

添加计数器

接下来添加一个计数器,每撞到一个小球就使计数器数值增加一,自然需要编辑PlayerController脚本,声明一个int类型的变量,在Start函数中初始化为0,在每一次碰撞到小立方体后都增加一,这似乎是一个很简单事情,这里还特地将count每次更新后的值都打印到控制台来验证其正确性。

private int count;
void Start()
{rigidbodyPlayer = GetComponent<Rigidbody>();count = 0;
}
void OnTriggerEnter(Collider other)
{if (other.gameObject.CompareTag("PickUp")){other.gameObject.SetActive(false);count++;Debug.Log(count);}
}

添加UI在游戏界面中显示分数

显然,将分数显示在游戏界面中才是更好的选择,这里需要用到UI组件。
在Hierarchy面板中右键,选择UI->Text,就会创建一个UI组件,但是我们会发现其实Text外还有一层Canvas(画布),下方还出现了一个EventSystem,这些都是Unity为我们自动创建的,这是因为:

The single most important thing to know about these additional items is that all UI elements must be the child of a canvas to behave correctly.
(所有的UI元素都必须是一个Canvas(画布)的子元素才能正常工作)

这里将Text命名为CountText,这时候的CountText处于一个非常奇怪的位置,接下来我们来调整Text的位置。

在Inspector面板中,我们可以调整Text显示的内容,字体的样式,字体颜色以及这个UI组件的位置,先把文字显示改为Count Text,接下来改变其字体颜色为白色。

接下来调整Text的位置,找到Inspecctor的Rect Transform,可以看到UI的Transform和一般GameObject的定位方式不同,这个位置的确定是相对于游戏屏幕的,点击左边的这个方框,展开位置选择的面板,根据提示:按住Shift键选择中心轴(pivot),按住Alt键选择位置(position)。我们选择同时按住Shift和Alt键,将Text放到Canvas的左上角:

这样就可以看到Count Text放置到了Game窗口的左上角。接下来可以改变Rect Transform的Pos X的值和Pos Y的值让Count Text稍微离左边缘和顶部边缘一段距离:

编辑脚本来显示分数

接下来当然是将分数显示到Text中,继续编辑PlayerController脚本,首先需要添加新的Namespace:

using UnityEngine.UI;

然后自然需要创建一个Text变量来表示CountText的一个引用,我们将此Text变量声明为public的类型,为了可以在Inspector中对其进行直接的赋值。接下来要初始化CountText中所显示的文字,使用Text的text变量即可,在Start函数中进行初始化,然后再每一次碰撞到小立方体的时候再重新更新Text的内容:

public Text countText;
void Start()
{rigidbodyPlayer = GetComponent<Rigidbody>();count = 0;countText.text = "Count: " + count.ToString();
}
void OnTriggerEnter(Collider other)
{if (other.gameObject.CompareTag("PickUp")){other.gameObject.SetActive(false);count++;countText.text = "Count: " + count.ToString();}
}

保存脚本回到Unity,将CountText拖动到Inspector中新产生的这个Text变量处来实例化它即可。

运行游戏,完美!

添加完成提示
最后,当所有的小立方体都被收集后,再屏幕中心显示“You Win!”的字样,这看起来就很简单了,同样是:添加一个新的Text组件、命名、改变字体颜色大小和位置、在脚本中新建一个Text变量、在Start函数中将其初始值设为空、满足count值大于等于8的时候即显示“You Win!”、将新的Text拖动到Inspector面板中的变量处。
主要的代码:

public Text winText;
winText.text = "";
if (count >= 8)
{winText.text = "You Win!";
}

运行游戏,完美!

Build游戏

最后就是创建我们的游戏了!Unity创建游戏的平台非常广泛,我们可以无需任何其他插件的前提下创建Windows、Mac和Linux平台下的游戏,但是如果创建诸如Android、IOS端的游戏需要额外的工作,比较复杂,以后会单独提到,这里先创建一个Windows平台的.exe文件。
先保存Scene,然后选择File下的Build Settings…。

默认即PC,Mac & Linux Standalone,这里还需要我们通过Add Open Scene来选择我们需要创建的Scene,不过本游戏只有一个Scene,不进行选择也是可以的。点击Build,选择要保存到目标目录,然后稍等片刻,就会得到了最终的.exe文件。


打开文件即可直接运行,整个游戏的所有工程也就全部完成了!


游戏完美运行!
游戏完美运行!
参考资料:https://unity3d.com/learn/tutorials/s/roll-ball-tutorial
本节内容的完整官方教程视频分享(英文无字幕):https://pan.baidu.com/s/1TNMMFjs7pZqLPhGQZ1tPqQ 提取码:1u70

【学习】Unity3D滚球游戏 原理及实现相关推荐

  1. 制作滚球游戏学习Unity3D

    从创建项目开始 创建一个项目 打开unity,在Projects中可以查看当前的本地项目或者云端项目,点击New project或者右上角的New都可以新建项目. 然后在1处填写创建项目的名称,2处选 ...

  2. 【Unity3D】二、制作滚球游戏学习Unity3D(下)

    上一篇文章:https://blog.csdn.net/qq_38962621/article/details/86930742 创建碰撞小立方体 新建Cube 我们在游戏场地中加入一些旋转的小方块儿 ...

  3. 【Unity3D】二、制作滚球游戏学习Unity3D(上)

    从创建项目开始 创建一个项目 打开unity,在Projects中可以查看当前的本地项目或者云端项目,点击New project或者右上角的New都可以新建项目. 然后在1处填写创建项目的名称,2处选 ...

  4. 滚球游戏(动态规划)

    某滚球游戏规则如下:球从入口处(第一层)开始向下滚动,每次可向下滚动一层,直到滚至最下面一层为止.球每次可滚至左下.下方或右下三个方格中的任意一个,每个方格都有一个得分,如样例所示.第1层有1个方格, ...

  5. 滚球游戏(数字三角形的变形)

    问题 F: 滚球游戏 [命题人 : admin] 时间限制 : 1.000 sec 内存限制 : 128 MB 题目描述 某滚球游戏规则如下:球从入口处(第一层)开始向下滚动,每次可向下滚动一层,直到 ...

  6. Unity 滚球游戏

    步骤一 创建滚球 Hierarchy界面下创建一个球体(sphere),命名为Player;创建地面,命名为Plane. 给Player增加一个组件Rigidbody. Project界面下创建文件夹 ...

  7. html代码3D滚球游戏代码,滚球控制系统代码

    [实例简介] 基于stm32f407的滚球控制系统代码的嵌入式部分 嵌入式接收视觉传送的关于小球的位置信息(x,y)通过pid处理之后 驱动舵机控制板子运动使小球到达指定位置 [实例截图] [核心代码 ...

  8. 【Unity学习第二天】滚球游戏学习(Roll A Ball)

    基本流程 ** 0.在基础的地面上会有一个小球,通过控制小球的滚动,吞吃地面上的一些小块. 1.创建基础场景,包括地面,主角,触碰小块. ① 通过材质设置修改相关物体的颜色/光滑度等显示. ② 重复出 ...

  9. unity fixedupdate_Unity之滚球游戏(上)

    程序员那些事 真正的程序员喜欢兼卖爆米花,他们利用CPU散发出的热量做爆米花,可以根据米花爆裂的速度听出正在运行什么程序. 创建一个项目 打开unity,在Projects中可以查看当前的本地项目或者 ...

最新文章

  1. 在神经网络中使用dropout
  2. 信息学奥赛一本通(1174:大整数乘法)
  3. Servlet之前端web数据与后台Java数据进行交互
  4. hive jdbc 访问 配置_Hive入门级教程(详细)
  5. pandas.Series
  6. 2021 全国大学生电子设计竞赛题目
  7. Teechart图表应用技术详解—第四章之工具组件概述
  8. 练手python_在图像上增加数字
  9. 网闸端口限制时,用HaneWin NFS Server来部署单一接口来交互,实现挂载便于访问
  10. eNSP交换机配置IP
  11. 浅谈python深拷贝和浅拷贝
  12. 【科软课程-信息安全】Lab13 Packet Sniffing and Spoofing
  13. 一张图看懂手机CPU性能——手机CPU性能天梯图
  14. 云谦:谈谈前端框架的趋势与实践
  15. gtx1050ti和gtx1650哪个好
  16. 一道积分不等式的证明
  17. ubuntu下使用QT编译 No such file or dire解决
  18. 回溯法,分支定界法求解n后问题
  19. tvOS游戏开发系列(SpriteKit)之准备工作(一)
  20. 怎么修改设置路由器默认密码

热门文章

  1. 【深度补全算法】基于RGBD相机的深度补全算法(非Lidar)论文与GitHub代码总结
  2. 关于 Linux 输入正确账号密码显示 Sorry,that did not work的问题
  3. 虚拟机配置IIS服务
  4. Magicodes.IE 2.2发布
  5. HTML标签:头部相关标签
  6. AlarmManager轮训
  7. vue百度地图API、获取当前经纬度以及地理位置
  8. ADSL DNS服务器地址大全
  9. ORA-27063: skgfospo: number of bytes rea
  10. 马思瑞美式发音课(第一课)