Unity3D_(游戏)2D简单游戏制作过程:捕获高空掉落保龄球
游戏介绍:通过鼠标的左右移动,可以控制帽子的移动,当帽子接到下落的保龄球时,会出现火花效果。没有接到保龄球时,保龄球落到草地上,过10S后会自动消失。
实现效果:
素材+Unity3D源代码:传送门
实现过程:
一、搭建基本场景
创建工程时选择2D正交视角,此时只有一个名为Main Camera的摄像机对象
为了使得游戏对象在场景中的层次不会错乱,可以创建不同的工作层次来管理游戏对象,使2D游戏场景的层次更加分明,游戏对象之间的操作也更加方便
选择菜单栏中的Edit->Project Settings->Tags and Layout命令(或者直接单选编辑器右上方的Layout->Edit Layout),在Inspector视图中,单机Sorting Layouts下的按钮,讲Layer ID 1命名为Background,再次单价Sorting Layout下的按钮,讲Layer ID 2命名为Foreground
Unity支持所有资源都可以通过以下三种方法进行导入:
1、直接将资源复制到项目文件夹下面的Assets文件中
2、直接将资源拖动到Project视图的Assets文件夹中
3、依次打开菜单栏中的Assets->Import New Asset...进行导入
(1)天空
创建一片天空,用来当做游戏背景的一部分。在场景中创建一个Sprite,依次选择菜单栏中的GameObject->2D Object->Sprite命令,重命名为sky
设置天空Sprite的纹理、工作层的顺序。在Inspector中将Sprite图片背景改为skySprite,并将Sorting Layout属性值设置为Baclground,Order in Layout属性值设置为0,设置参数如下
·Sprite:Sprite的图片信息。
·Color:Sprite的颜色
·Material:Sprite的材质。
·Sorting Layer:Sprite的分类层。单机右侧下拉按钮可以选择或者添加新的分层,层级越靠前,优先级越高,相同情况下后被渲染。
·Order in Layer:Sprite所在层中的顺序。数值越大,优先级越高,相同情况下后被渲染。
(2)草地
依次选择菜单栏中的GameObject->2D Object->Sprite命令,在场景中创建一个Sprite,重命名为grass(草地Sprite在工作层顺序要比天空高,这样能将草地显示在前面)
设置草地Sprite的纹理,工作层的顺序。在Inspector中将Sprite图片背景改为GrassSprite,并将Sorting Layout属性值设置为Baclground,Order in Layout属性值设置为1,设置参数如下
此时图片不能填充满地面背景,可以选择多复制些草丛,并依次拖动Sprite,将sky下方背景被草地填充满
(有必要换可以创建一个空对象来管理游戏背景,依次选择菜单栏中GameObject->Create Empty命令,创建一个空对象,将其命名为Background,将sky和grass对象拖动到Background中,与Background建立父子关系)
二、添加角色和控制
(1)创建Sprite动画
Unity3D能自动切割Sprite,将一张多纹理的图片切割成多个Sprite,并且这些Sprite将保持在同一个图片文件中,在Project视图中,选中切割图片,在图片的Inspector视图中,将Sprite Mode设置为Multiple,然后单击下面的Sprite Editor按钮,在弹出的Sprite Editor对话框左上角的Slice按钮中单击另一个同名的Slice按钮,最后单击Apple俺就,Sprite图片就会自动切割完成
自动切割完成后,Sprite动画就被切割成8长小图,接下来要制作天鹅飞行的动画
依次选择菜单栏中的GameObject->2D Object->Sprite命令,创建一个Sprite,并改名为swan,在Select Sprite对话框中选择swan_sheet_0,在Inspector视图中将Sorting Layout属性值设置为Background,Order in Layout属性值设置为1,
给天鹅Sprite创建一个煽动翅膀的动画
选中swan,依次选择菜单栏中的Window->Animation命令,在演出的Animation对话框中,单选左侧的按钮,选择Create New Clip,然后在弹出的Create New Aniamtion对话框中选择Assets下方的Animation文件夹,将文件命名为swan,保存
在Project视图中的Animation文件夹中,会创建出2个swan文件,其中一个是swan动画片段,另一个是swan动画控制器
以Sprite的变化作为动画帧,在Hierarchy视图中选中swan,依次选择菜单栏中的Window ->Animation命令,在打开的Animation视图中,将Sampke属性值设置为10,然后单击Add Property按钮,在弹出的选择列表中单击Sprite Renderer左侧的播放按钮(必须先将Sampke属性值设置为10)
将末尾处无用的关键帧删除。在Animation视图中,选中1:00选的关键正右击关闭,在弹出快捷菜单每0.01s创建一个一个帧动画(改变帧动画只需要修改一帧的Inspector下的Animator下的Controller,最后面有参考书籍,这里出问题了可以按照课本上多O(∩_∩)O~)
最终预览效果:
添加脚本,实现天鹅飞行的效果
using System.Collections; using System.Collections.Generic; using UnityEngine; public class SwanMove : MonoBehaviour { //swan的移动速度 private float moveSpeed = 4; // Use this for initialization void Start () { //设置天鹅的初始位置 transform.position = new Vector3(22, 3, 0); } // Update is called once per frame void Update () { if(transform.position.x>-22){ //天鹅移动 transform.Translate(Vector3.right * -moveSpeed * Time.deltaTime); } else{ transform.position = new Vector3(22, 3, 0); } } }
将脚本绑定到天鹅上,播放按钮实现天鹅从左侧飞向右侧
三、帽子对象
(1)将HatBackSprite图片拖动到Hierarchy视图中,将其命名为Hat,为了使帽子显示在所有背景的前方,将Sorting Layout属性值设置为Foreground,Order in Layout的属性值为0,
(2)在Project视图中的Sprite文件夹中,将Hierarchy拖动到Hat上,建立父子关系,将Sorting Layout属性值设置为Foreground,Order in Layout属性值为2,将帽子后半部分的Order in Layer属性值为0,前半部分的Order in Layer属性值为2,前半部分的Order in Layer属性值设置为2,目的是使得保龄球Sprite的优先级在两者之间,实现保龄球在被帽子接住候达到进入帽子的视觉效果
(3)创建保龄球Sprite,改名为BowlingBall,在BowlingBall的Inspector视图中,将Sorting Layout值设置为Foreground,Order in Layout的值设置为1
(4)为保龄球Sprite添加刚体,使其有自由下落的效果,并添加碰撞刚体,使其与别的碰撞体之间有碰撞的效果。
在Hierarchy视图中选中BallingBall,依次选择菜单栏中的Component->Physics 2D->Rigidbody 2D(2D刚体)命令,给BowlingBall添加一个Rigidbody 2D组件。再一次选择菜单栏中的Compent->Physics 2D->Collider 2D(2D圆形碰撞体命令),给BowlingBall添加一个Circle Collider 2D组件
(5)添加脚本,实现保龄球自由下落
using System.Collections; using System.Collections.Generic; using UnityEngine; public class GameController : MonoBehaviour { //BowlingBall public GameObject ball; private float maxWidth; private float time = 2; private GameObject newball; // Use this for initialization void Start () { //将屏幕的宽度转换成世界坐标 Vector3 screenPos = new Vector3(Screen.width, 0, 0); Vector3 moveWidth = Camera.main.ScreenToWorldPoint(screenPos); //获取保龄球自身的宽度 float ballWidth = ball.GetComponent<Renderer>().bounds.extents.x; //计算保龄球实例化位置的宽度 maxWidth = moveWidth.x - ballWidth; } // Update is called once per frame void FixedUpdate () { time -= Time.deltaTime; if(time<0) { //产生一个随机数,代表实例化下一个保龄球所需要的时间 time = Random.Range(1.6f,1.8f); //在保龄球实例化位置的宽度内产生一个随机数,来控制实例化保龄球的位置 float posX = Random.Range(-maxWidth, maxWidth); Vector3 spawnPosition = new Vector3(posX,transform.position.y,0); //实例化保龄球,10秒后销毁 newball = (GameObject)Instantiate(ball, spawnPosition, Quaternion.identity); Destroy(newball,10); } } }
(6)将脚本绑定到保龄球上
(7)创建一个C#脚本,用来控制帽子的移动
using System.Collections; using System.Collections.Generic; using UnityEngine; public class HatController : MonoBehaviour { public GameObject effect; private Vector3 rawPosition; private Vector3 hatPosition; private float maxWidth; // Use this for initialization void Start () { //将屏幕的宽度转换成世界坐标 Vector3 screenPos = new Vector3(Screen.width, 0, 0); Vector3 moveWidth = Camera.main.ScreenToWorldPoint(screenPos); //计算帽子的宽度 float hatWidth = GetComponent<Renderer>().bounds.extents.x; //获得帽子的初始位置 hatPosition = transform.position; //计算帽子的移动速度 maxWidth = moveWidth.x - hatWidth; } // Update is called once per frame void FixedUpdate () { //将鼠标的屏幕位置转换成世界坐标 rawPosition = Camera.main.ScreenToWorldPoint(Input.mousePosition); //设置帽子将要移动的位置,帽子移动范围控制 hatPosition = new Vector3(rawPosition.x, hatPosition.y, 0); hatPosition.x = Mathf.Clamp(hatPosition.x,-maxWidth,maxWidth); //帽子移动 GetComponent<Rigidbody2D>().MovePosition(hatPosition); } }
(这个脚本挺好用的,不采用折叠)
为帽子添加刚体并开启is Kinematic(是否运动学,开启的话 游戏对象不会受到物理引擎的影响只能通过Transfrom(几何变化组件)属性来对其操作)
在Hierarchy视图中选中Hat,依次选择菜单栏中的Component->Physics2D Rigidbody 2D命令,然后在Hat的Inspector视图中,将Gravity Scale设置为0(防止Hat下落),并选中Fixed Angle属性复选框
创建2D物理阻挡
给帽子添加碰撞体,使其与保龄球可以发生碰撞。在Hierarchy视图中选种Hat下的HatForntSprite,依次选择菜单栏中的Component->Physics 2D->EdgeCollider 2D(2D边缘碰撞)命令,为HatFrontSprite添加一个Edge Collider 2D组件,然后在Inspector视图中单击Edit Collider左侧按钮,在Scene视图中编辑Edge Collider 2D,使得Edge Collider 2D组件包裹住Hat
(当小球碰撞到这些绿色的线条就会被弹开)
给帽子添加触发器,用来判断保龄球是否进入帽子,按照上一步步骤,给Hat添加一个Edge Collider 2D主键,使得Edge Collider 2D在Hat底部呈一条直线
添加保龄球进入触发器后删除保龄球的代码,这样帽子可以持续接取保龄球
using System.Collections; using System.Collections.Generic; using UnityEngine; public class HatController : MonoBehaviour { public GameObject effect; private Vector3 rawPosition; private Vector3 hatPosition; private float maxWidth; // Use this for initialization void Start () { //将屏幕的宽度转换成世界坐标 Vector3 screenPos = new Vector3(Screen.width, 0, 0); Vector3 moveWidth = Camera.main.ScreenToWorldPoint(screenPos); //计算帽子的宽度 float hatWidth = GetComponent<Renderer>().bounds.extents.x; //获得帽子的初始位置 hatPosition = transform.position; //计算帽子的移动速度 maxWidth = moveWidth.x - hatWidth; } // Update is called once per frame void FixedUpdate () { //将鼠标的屏幕位置转换成世界坐标 rawPosition = Camera.main.ScreenToWorldPoint(Input.mousePosition); //设置帽子将要移动的位置,帽子移动范围控制 hatPosition = new Vector3(rawPosition.x, hatPosition.y, 0); hatPosition.x = Mathf.Clamp(hatPosition.x,-maxWidth,maxWidth); //帽子移动 GetComponent<Rigidbody2D>().MovePosition(hatPosition); } //有碰撞物体进入触发器时触发 private void OnTriggerEnter2D(Collider2D col) { GameObject neweffect = (GameObject)Instantiate(effect, transform.position, effect.transform.rotation); neweffect.transform.parent = transform; Destroy(col.gameObject); //删除该碰撞的物体 Destroy(col.gameObject,1.0f); } }
在草地下方添加一个碰撞体,用来阻挡保龄球继续下落。
依次选择菜单栏中的GameObject->Create Empty命令,创建一个空对象,将其命名为ground,选中ground,依次选择菜单栏中的Component->Physics 2D->Box Collider 2D命令,最后在ground的Inspector视图中,调整ground的Offset和Size属性值
当没有接住保龄球,保龄球在草地上停留10S后会自动消失
到此时就已经实现游戏基本功能
四、添加2D游戏效果
为了鼓励玩家操作,让玩家更有参与感,可以给当玩家接收到天空落下的求就会出现火花的粒子特效,下面来实现最终游戏的效果
首先导入火花粒子资源包
依次选择菜单栏中的Asset->Import Package->Custom Package命令,导入Effect,unitypackage资源包进入到工程中,选中Effect文件夹下的Effect粒子预设体,将Particle System组件中的Renderer属性值下的Sorting Layout设置为Foreground,Order in Layout设置为1
点击Hat Controller(Script)组件下的Effect按钮,在弹出的Select GameObject对话框中选择Effects
此时点击播放按钮,就可以实现通过鼠标的左右移动,可以控制Hat的移动,当Hat接到下落的保龄球时,会出现火花效果
End!
参考书籍《Unity 5.X从入门到精通》