经过第一章学习我默认大家应该已经懂了Unity的最基础的东西了,我们现在开始了解做俄罗斯方块这类2D项目的关键,UGUI。
把素材放进我们的resources里面,方便读取。
然后我们把其的值转换成sprite2D,这一步是因为俄罗斯方块我们是用Unity的Image去弄,所以转换成sprite才能贴上去。
然后我们创建我们需要的UI,如下图
创建完成之后如下图
我们可以看到他会自动生成Canvas和EventSystem,Canvas是UI的画布,你可以理解为它就是2D化的屏幕,随着分辨率改变它也会改变,然后EventSystem就是他们的事件监听组件,有了它那些UI的功能才能实现(比如说Button,Toggle等等),大家可以用自己的Unity尝试一下,创建个Button,在运行状态下有EventSystem和无EventSystem的区别。
然后我们在左上点击2D按钮,在2D视角去调UI会比较简单,如下图
在做一个项目之前我个人习惯是先弄好UI的Demo然后再去做主框架,最后再上UI的素材(因为美工做UI素材也要一点时间),好了,现在我们先想想有些什么UI,一个俄罗斯方块游戏的话,我们弄一个暂停按钮,然后还有一个退出按钮,还有一个开始按钮,如下图
然后记得记得记得要改这些UI的命名,因为后期你们做真正的项目的时候不会是一两个UI的存在,而是一大堆UI,那么你的命名就是你区分哪个是哪个的关键(血的教训)。
定义好这个之后就是去排一下UI了,俄罗斯方块嘛,首先得有一个框(有能力的可以直接代码生成一个,我的话教大家最简单的手拼,如果代码生成中遇到什么问题的可以留言你的QQ号,我和你一起去探讨解决撒),
拼好了整体,然后我们开始下一步,定义好预设,就是我们的方块预设。
我拼了四个形,记住父物体要在中心点,不然到时动态生成的时候会有问题。然后统一拉到Resources里面作为预设体,
然后我们可以把场景中的删掉了
到了这里之后我们可以开始加代码了,在写代码之前我们要明白一点,就是什么叫面向对象,什么叫面向过程,其实这一点背所谓的要素并没有太大的帮助,因为这些主要是要看你对于一个项目的理解的,面向对象我的理解就是你的代码是针对全局去构思的,把东西分成一个一个的功能模块,这样做主要是让程序最终运行起来是最精简,最不累赘的,而代码方面是最简洁,逻辑性最高,并且当你某一个功能除了问题你能第一时间知道从哪一块去查这个问题的。
说了一堆废话之后,我们开始加代码,俄罗斯方块,游戏的主模块无非就是开始,生成,移动,限定区域,消除,失败判定,过关判定,难度判定。总结完这一段之后我们就可以很清楚的看到,一切的始端就是开始,那么我们先写开始代码。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class M_Begin : MonoBehaviour {
static M_Begin TT;
/// <summary>
/// 单例代码
/// </summary>
/// <returns></returns>
public static M_Begin GetInstan()
{
return TT;
}
private void Awake()
{
TT = this;
}
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
public void ControlBegin()
{
}
}
这里的话要提到的一点是单例,大家可以上网查查具体定义,很多大神都有解释,但是作为新人的话,我那时候一直都不知道单例是怎么去用的,其实可以总结为,你一个Scene里面只挂载一个这个脚本,然后方便读这个脚本你把这个脚本静态公开出去,记住,这个脚本是场景内有且仅有一个才能用单例。我上面写道的把“TT”实现是放在Awake是为了防止要引用它的脚本会比他先,一般开始就引用的一般我都会放在start,单例和实例化放在awake,这样顺序就会更好,如果过多的话我建议是统一有一个脚本去唤醒引用他们,这样更保障不会因为先后顺序问题而导致脚本出错。然后我的函数ControlBegin就是用来开始时候被调用的,但是开始之后的内容我们还没写,所以我们接下来就是要写接收了开始之后的工作,没错,就是生成了。
public class M_Creative : MonoBehaviour {
GameObject[] AllTu;
bool HaveOne = false;//判定当前有一个已生成,true是可以生成,false是不可生成
public void BeginCreat()
{
for(int a=0;a<5;a++)
{
AllTu[a] = Resources.Load<GameObject>("Prefeb/" + a);//通过Resources去加载资源
}
}
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
if(HaveOne)
{
Shengcheng();
HaveOne = false;
}
}
void Shengcheng()
{
int Num = Random.Range(0, 5);
Instantiate(AllTu[Num]);
}
}
这里是生成代码,Resource就是读取我们之前放Resources的文件,不过我改了名字方便读取,如下
然后我们只要控制UI去让它生成,就可以生成我们想要的东西了,如下
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;//这里一定要加上引用,不然的话没办法定义UI
public class M_UI_MainUIControl : MonoBehaviour {
public Button Begin;
private void Awake()
{
Begin.onClick.AddListener(ListenBegin);//这是监听代码
}
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
/// <summary>
/// 监听开始按钮
/// </summary>
void ListenBegin()
{
M_Begin.GetInstan().ControlBegin();
}
}
完成这里之后我们要做的就是挂上代码了
记住,公开的Button那里一定要把开始那个按钮拉倒对应名字的地方
然后我们就可以点击开始实现生成了
然后我把除了UI脚本之外的其他脚本给大家挂上
M_Creative的:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class M_Creative : MonoBehaviour {
static M_Creative TT;
public static M_Creative GetInstan()
{
return TT;
}
GameObject[] AllTu=new GameObject[5];
bool HaveOne = false;//判定当前有一个已生成,true是可以生成,false是不可生成
public void BeginCreat()
{
for(int a=0;a<5;a++)
{
AllTu[a] = Resources.Load<GameObject>("Prefeb/" + a);//通过Resources去加载资源
}
}
private void Awake()
{
TT = this;
}
// Use this for initialization
void Start () {
}
/// <summary>
/// 接收生成指令
/// </summary>
public void SetCreative()
{
HaveOne = true;
}
// Update is called once per frame
void Update () {
if(HaveOne)
{
Shengcheng();
HaveOne = false;
}
}
void Shengcheng()
{
int Num = Random.Range(0, 5);
Instantiate(AllTu[Num],gameObject.transform);
}
}
M_Begin的:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class M_Begin : MonoBehaviour {
static M_Begin TT;
bool HaveBegin = false;//是否已经开始,防止二次点击Button时候再次开始导致代码混乱
public bool GetHaveBegin()
{
return HaveBegin;
}
/// <summary>
/// 单例代码
/// </summary>
/// <returns></returns>
public static M_Begin GetInstan()
{
return TT;
}
private void Awake()
{
TT = this;
}
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
public void ControlBegin()
{
M_Creative.GetInstan().BeginCreat();
M_Creative.GetInstan().SetCreative();
HaveBegin = true;
}
}
有什么不懂的欢迎留言提问