这个期末没有浓浓师生情。
在制作了一个《太空大战》的游戏之后,基本已经对Unity引擎的基本操作熟悉了,接下来就要开始在我喜欢的2D平面游戏方向的学习。
这是我的《太空大战》的链接:https://blog.csdn.net/weixin_43826242/article/details/85224287
做的有丶简陋,还是得继续学习才行,个人认为坚持是最关键的。
接下来是《Unity5.x从入门到精通》这本书的第七章,该章节的主题是创建基本的2D游戏场景。注意选择2D。
后面的过程比较简单,我就省略了,主要任务是先搭建整个游戏的背景。
根据书上说的,先创建两个Layer,一个是Foreground另一个是Background,分别代表前后两个层。
左上角Edit -> Project Settings -> Tags and Layers 然后选加号创建即可。
然后创建两个Sprite(精灵),我个人理解精灵就是2D中的角色素材模型。
然后一个Sprite做成天空的背景,另一个是草地,然后多复制几个就可以铺满底部了。
最好调整一下摄像头。然后背景的位置最好Reset一下,看着比较顺眼。
接下来是制作一个会飞的 “天鹅” 的Animation :
先选择天鹅的swan_Sheet资源,然后设置成Multiple,应该是表示他是一张图里面有多个元素,这样整理2D素材的时候一般比较方便,在需要的时候将必要的部分Slice出来即可。
接下来是Slice操作:
上图里面有个Sprite Editor ,直接点开大概就是第二张图的样子,然后左上角Slice -> Slice 就可以将8张小图全部分开了。
实际上拿到资源的时候已经是切割完成的了。
然后创建swan的精灵对象,把这个已经切割好的集合拖动到 swan 的 Sprite Renderer 中的Sprite上面。
紧接着是利用这8个小动画来制作天鹅飞行的逐帧动画:
通过左上角Window -> Animation -> Animation 来打开动画编辑(Ctrl + 6)
选中swan对象就能看到编辑器右边有创建新的Clip , 然后创建 , Samples 改为10 , 能看到有两个起始的关键帧,末尾那个删除就行。
接下来就是把8个分开的小图像一个一个拖到时间轴上让他导入就行了,作者自己的Unity好像出了点BUG,托上去之后不知道为什么没有预览了,只有时间点在上面,书上是有预览的8个连续的小图的,评论区求个指点!
做好之后就可以点编辑器上面的播放按钮就能在Scene视图看到天鹅飞行的动画。
紧接着是给天鹅写一个移动的C#脚本,让天鹅在画面上面移动。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SwanMove : MonoBehaviour {
//定义天鹅的移动速度
public float swanspeed;
void Start () {
//定义天鹅的初始位置
transform.position = new Vector3(11.0f, 3.55f, 0);
}
void Update () {
//当天鹅还没有移出屏幕的时候
if (transform.position.x > -12.7f)
{
//让天鹅向前移动
transform.Translate(Vector3.right * swanspeed * Time.deltaTime);
}
else
{
transform.position = new Vector3(11.0f, 3.55f, 0);
}
}
}
写完上面的脚本组件直接给天鹅添加就可以了。
接下来是做一个帽子和保龄球:具体的操作几乎相似,直接从资源列表拖动即可
帽子有上下两半,因此要有一个父子关系。
在设定的时候前面的帽子是Foreground , order 顺序是 2 ;后面的帽子是Background , order 顺序是 0
然后制作保龄球,是Foreground , order 顺序是 1
order顺序这样设置可以表现出保龄球进入帽子的视觉效果。
从下面可以看出顺序设置的效果:
接下来,添加GameController来控制保龄球在天上随机下落
先新建一个Empty Object ,命名为GameObject , 然后写一个C#脚本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameController : MonoBehaviour {
//定义公共的保龄球游戏对象
public GameObject BowlingBall;
private float maxWidth;
//这里的time相当于多长时间之后开始掉落第一个
public float time;
private GameObject newBowlingBall;
// Use this for initialization
void Start () {
//将屏幕的坐标转换成世界坐标
Vector3 screenPOS = new Vector3(Screen.width, 0, 0);
Vector3 moveWidth = Camera.main.ScreenToWorldPoint(screenPOS);
//获取保龄球自身的宽度
float ballWidth = BowlingBall.GetComponent<Renderer>().bounds.extents.x;
//计算保龄球实例化位置的宽度
maxWidth = moveWidth.x - ballWidth;
}
// Update is called once per frame
void Update () {
//倒计时下落保龄球
time -= Time.deltaTime;
//如果time为0了,就重新生成一个time作为下一次的时间,同时实例化一个保龄球
if (time < 0)
{
time = Random.Range(1.5f, 2.0f);
float posX = Random.Range(-maxWidth, maxWidth);
//赋值给实例化的位置
Vector3 spawnPOS = new Vector3(posX, transform.position.y, 0);
//实例化一个保龄球,同时返回给newBowlingBall这个游戏对象,一会销毁就销毁就可以指定这个游戏对象销毁
newBowlingBall = (GameObject)Instantiate(BowlingBall, spawnPOS, Quaternion.identity);
//销毁这个游戏对象
Destroy(newBowlingBall, 10f);
}
}
}
用鼠标控制帽子的移动:给帽子添加2D刚体并且把Gravity Scale 设为防止帽子下落,冻结Z轴防止帽子旋转
写一个HatController脚本添加到Hat的父类对象上
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class HatController : MonoBehaviour {
//定义帽子的位置和鼠标的位置变量
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;
}
//FixedUpdate在每一次的物理时间完成的时候调用
private void FixedUpdate()
{
//将鼠标的位置转换成世界坐标
rawPosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
//设置帽子将要移动的位置和帽子移动的范围控制
hatPosition = rawPosition;
hatPosition.x = Mathf.Clamp(hatPosition.x, -maxWidth, maxWidth);
//移动帽子
GetComponent<Rigidbody2D>().MovePosition(hatPosition);
}
}
然后给帽子添加Edge Collider , 勾选 Is Trigger 表示有碰撞事件触发
再在HatController中加入以下部分代码来控制碰撞事件
private void OnTriggerEnter(Collider other)
{
//当有物体和帽子发生碰撞的时候就删除这个物体
Destroy(other);
}
在草地下方再添加一个碰撞体用来阻止保龄球继续下落,相同的步骤,然后就做成这样,注意一下偏移量offset别动
做到这里其实作者就发现一个无语的bug,因为这一章没使用Tags对游戏物体分类,然后上面帽子的碰撞器一碰到下面的草地就把草地的碰撞器给删除了,导致保龄球还是接不住。。果真这一章就是基础的小操作而已。加上tag之后就可以解决这种情况。
最后是给接保龄球来点粒子特效
发现一个问题,资源包package不能直接从压缩文件里拖进资源栏,Unity显示不能解压。
在特效的预置体调整一下 排序层 和 层的顺序
再在HatController中添加下面的代码
//特效对象
public GameObject FX;
。。。
private void OnTriggerEnter2D(Collider2D other)
{
//当有物体和帽子发生碰撞的时候就删除这个物体
if (other.CompareTag("BowlingBall"))
{
//实例化特效FX
GameObject newFX = (GameObject)Instantiate(FX, transform.position, transform.rotation);
//将这个实例化的新特效作为帽子的子物体,这样可以让特效跟着帽子移动一会
newFX.transform.parent = transform;
Destroy(other.gameObject);
//延时销毁特效
Destroy(newFX, 1.0f);
}
}
最后记得把特效的预制体拖动到帽子的脚本组件上,这样整个第七章的内容就完成了。
非常的简单,也很基础,希望里面的知识我都可以牢记。
附上看到的不错的内容吧,都是在本章中拓展学习到的内容:
1. Unity中屏幕坐标、视图坐标和世界坐标的相互转换
https://www.jianshu.com/p/b5b6ac9ab145
2. Unity中Tilling和OffSet的运用
https://blog.csdn.net/weixin_39591280/article/details/80893349
3. Unity的输出文件使用winrar快速打包成exe文件(好用)
https://blog.csdn.net/qq_27124771/article/details/82085137
最后是这个项目的最终打包作品exe,发到了github上面,还有一共3个脚本,虽然很简单,就当保留我的学习轨迹。
https://github.com/dzzhyk/Hat-and-Bowlingball-Chapter-07-
继续加油!