我们知道在游戏中,游戏等级不是在搭建UI时写死的,而是动态加载的.
比如,消灭星星,等级的信息是根据玩家的数据而改变的,不同的等级可能得到的星星数量不同.
动态加载时在搭好的UI界面通过Resources,load动态加载进去,
资源工程文件:https://pan.baidu.com/s/1RIF_fdFOye6sFu82_7aUpw
项目目标.
步骤:
1.首先还是搭建UI界面,层次等级如下:
SelectLevelUI是UI界面背景,
TitleView 是TitleBar,不做解析
LevelCount: 游戏等级的承载体,游戏等级的直接背景,等级元素将动态生成在此下面,
需要对他进行预布局,作为元素的载体,同时,还会最为每个元素Toggle的组头,
每个元素都以此为分组.
其中,Cell Size是其内每个元素的大小设置,习惯上LevelCount的尺寸大小根据排列的Cell相关,
cell 直接填满LevelCount,每个元素的具体布局则在Cell内具体排布.
Cell 也就是此处的Level,是对具体游戏等级的具体排布.
背景有两种颜色的image,分别表示正常和被选中时,将分别拖入到Toggle里,
Target Graphic :Normal_bg
Graphic: Hight_bg
Group: 就是上面提到的levelCount父物体为分组;
将搭建好的level元素做成预制体防止丢失.
以上为UI的搭建
-------------------------------------------------------------------------------------------------------------------
2.代码编写:
2-1.制作Model;
一个level有多少数据,独处出来建一个数据类,取名LevelData
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/*
* MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,
* 一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码,
* 将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,
* 不需要重新编写业务逻辑。MVC被独特的发展起来用于映射传统的输入、处理
* 和输出功能在一个逻辑的图形化用户界面的结构中。
*/
//数据类,模型类,MPC->Model->View->Controller思想 这个类就属于M即 Model
//level的显示依据于数据
public class LevelData
{
public int level_id; //关卡的ID,通过ID我们可以读取本地的配置文件(CSV文件读取,本地数据库的读取)
//来获取客户端应该显示的数据
public string level_name; //关卡名字
public int level_number; //关卡编号
public int level_star_number; //关卡星星数
public string level_icon; //关卡背景
}
关卡背景Icon是有加载路径确认的,因此是字符串路径.
2-2,建好数据模型后,通过此模型创建数据,但是他创建出来只是数据,没有赋给模型.因此
还需要创建模型,赋值给模型,将数据赋值到模型,即挂载到模型上的值
初始化模型:
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using UnityEngine.UI;
- public class Level : MonoBehaviour
- {
- public int level_id; //每个关卡的ID号
- public Text level_name; //关卡名字
- public Text level_number; //关卡编号
- public Image level_icon; //关卡背景图标
- public Image level_star_one; //一星
- public Image level_star_two; //二星
- public Image level_star_three; //三星
- public void InitLevelWithLevelID(int id)
- {
- level_id = id;
- level_name = transform.Find("LevelInfo/LevelName").GetComponent<Text>();
- level_number = transform.Find("LevelInfo/LevelNumber").GetComponent<Text>();
- level_icon = transform.Find("LevelIcon").GetComponent<Image>();
- level_star_one = transform.Find("LevelStar/StarCenter").GetComponent<Image>();
- level_star_two = transform.Find("LevelStar/StarLeft").GetComponent<Image>();
- level_star_three = transform.Find("LevelStar/StarRight").GetComponent<Image>();
- }
- }
2-3,创建数据,创建模型,动态加载到UI中
2-3-1 创建临时数据,添加到链表List _datas上,
获取等及元素的父物体,获取等级元素模型
根据得到的临时数据创建每个等级元素.:
- void CreateLevel()
- {
- //因为我们以后的数据是网络请求而来,所以客户端不能保证一定能得到数据
- //所以一般在处理网络请求数据的时候,一定要在本地做好保护,因为一旦不写保护,
- //很可能因为的得不到数据崩溃,学医保护最多就是不显示数据而已,不会让程序中断.
- //客户端程序员要养成良好的习惯,任意数据(只要是从后台获取的就一定得做保护)
- //比如说前端要显示一个int数据,该数据从后端读取,没有意外获取的就是int,但是也有可能
- //因为后端手误,返回给你的是一个float数据,那我们知道高精度转呗低精度最多就是丢失精度而已
- //但是如果反过来,低转高,需要强转,一旦类型不匹配,你有没有强转,此时程序崩溃.
- if (_datas.Count>0)
- {
- for (int i = 0; i < _datas.Count; i++)
- {
- tempLevel= Instantiate(_level) as GameObject;
- //设置父节点
- tempLevel.transform.parent = _levelParent;
- //设置位置
- tempLevel.transform.localPosition = Vector3.zero;
- //设置缩放
- tempLevel.transform.localScale = Vector3.one;
- //设置旋转
- tempLevel.transform.localRotation = new Quaternion();
- //------------------->处理数据
- Level levelItem = tempLevel.AddComponent<Level>();
- //根据集合里的ID进行初始化
- levelItem.InitLevelWithLevelID(_datas[i].level_id);
- //设置名字
- levelItem.level_name.text = _datas[i].level_name;
- //设置关卡编号
- levelItem.level_number.text = _datas[i].level_number.ToString();
- //设置关卡的背景图片
- string path = string.Format("{0}{1}", "Icon/", _datas[i].level_icon);
- levelItem.level_icon.sprite = Resources.Load(path, typeof(Sprite)) as Sprite; //typeof (Sprite) as Sprite 制定类型
- //设置关卡星级
- ShowStar(_datas[i].level_star_number, levelItem);
- toggle = levelItem.GetComponent<Toggle>();
- toggle.onValueChanged.AddListener
- (
- (isOn) =>
- {
- SelectLevel(isOn, levelItem);
- });
- }
- }
- }
因为元素父物体有自动布局,因此只需创建出来,将元素的父物体设置好,就能自动布局.
创建一个真正的元素,给它添加脚本组件,将其他组件的具体属性赋值,显示其星星数量并监听被选中后的事件.
这样动态加载游戏等级做好了,详情见首部工程源代码!