GameFramework框架实现七天活动功能
功能需求
功能需求如图,首先分析怎么做,搭UI很简单,但是如何更简单更加易于修改与维护呢?
算了,这些先不想,需要读表,那就先把表导入进去吧
由这两个表可以看出,要先从表SevenDayLogin中读出奖励描述,图片ID,然后通过ID在UIItem表中得到图片具体信息路径,资源名.通过这些东西,我们就可以很好的找出图片资源了
然后编写两个表的读表脚本并加进ProcedurePreload流程中
如图,代码如下
UIItem表
using GameFramework.DataTable;
using System.Collections.Generic;
namespace StarForce
{
public class DRUIItem : IDataRow
{
/// <summary>
/// 道具编号。
/// </summary>
public int Id
{
get;
protected set;
}
/// <summary>
/// 道具名称。
/// </summary>
public string ItemName
{
get;
protected set;
}
/// <summary>
/// 道具图片路径。
/// </summary>
public string PicPath
{
get;
protected set;
}
/// <summary>
/// 道具图片名称。
/// </summary>
public string PicName
{
get;
protected set;
}
/// <summary>
/// 道具价格。
/// </summary>
public int Price
{
get;
protected set;
}
/// <summary>
/// 道具价速度加成。
/// </summary>
public int SpeedAdd
{
get;
protected set;
}
/// <summary>
/// 道具价攻击力加成。
/// </summary>
public int AttackAdd
{
get;
protected set;
}
/// <summary>
/// 道具价防御力加成。
/// </summary>
public int DefenceAdd
{
get;
protected set;
}
/// <summary>
/// 道具描述。
/// </summary>
public string Des
{
get;
protected set;
}
public void ParseDataRow(string dataRowText)
{
string[] text = DataTableExtension.SplitDataRow(dataRowText);
int index = 0;
index++;
Id = int.Parse(text[index++]);
ItemName = text[index++];
PicPath = text[index++];
PicName = text[index++];
Price = int.Parse(text[index++]);
SpeedAdd = int.Parse(text[index++]);
AttackAdd = int.Parse(text[index++]);
DefenceAdd = int.Parse(text[index++]);
Des = text[index++];
}
private void AvoidJIT()
{
new Dictionary<int, DRUIItem>();
}
}
}
SevenDayLogin表
using GameFramework.DataTable;
using System.Collections.Generic;
namespace StarForce
{
public class DRSevenDayLogin : IDataRow
{
public int Id
{
get;
private set;
}
public string AwardName
{
get;
private set;
}
public string AwardDescribe
{
get;
private set;
}
public string LoginAwardItems
{
get;
private set;
}
public int LoginDays
{
get;
private set;
}
public void ParseDataRow(string dataRowText)
{
string[] text = DataTableExtension.SplitDataRow(dataRowText);
int index = 0;
index++;
Id = int.Parse(text[index++]);
AwardName = text[index++];
AwardDescribe = text[index++];
LoginAwardItems = text[index++];
LoginDays=int.Parse(text[index++]);
}
private void AvoidJIT()
{
new Dictionary<int, DRSevenDayLogin>();
}
}
}
注意名字别写错
UI分析
表也读完了,这个怎么做呢,老老实实拼UI呗
ok,UI拼完了,但是好low啊有没有,跟需求完全差十万八千里,怎么说.
解释一下,是因为这个一条一条的,明显重复,可以实例化出来,还有那个奖励的图片,同样可以实例化出来,读表读多少个就实例化多少个不是很爽,问题来了,Scroll View忘了怎么用了,先查查.
- 创建一个Scroll View并调节它的大小,展示出来的部分
- 左右滑的话Vertical勾掉,上下滑勾掉Horizontal
- 调整Content的大小,这里边是放你要展示的图片的,具体大小已展示物体多少来定
- 在content下放好要展示的东西,如果左右滑就删掉上下滑的滑动条,上下滑反之
- 然后调节Scroll View的透明度,记住如果要做预制体的话,不要删Image
- 现在就可以使用了,apply没有问题
- 等等,实例化出来的会按我们想要的效果排列吗?这个时候就用到了排版工具
奖励图片的话,搞个空节点当父物体好了,同样加上排版工具
测试下没问题,对了,Item不要放Content下,这个待会说
好了,UI拼完,拉成预制,在UIForm表中加入这个UI预制的名字
在UIFormId里加入这个名字和ID
OK,要打开这个Form,就在之前界面的活动的Btn上加个监听事件吧,
然后呢,就写SevenDayForm脚本挂载在UI预制体上
代码如下
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using GameFramework;
using GameFramework.DataTable;
using UnityEngine.UI;
namespace StarForce
{
public class SevenDayForm : UGuiForm
{
private GameObject itemPrefab;//预制模板
private int totalDays;//实例化多少格,即读表读出多少行
//Item的父节点
private Transform grid;
protected override void OnInit(object userData)
{
base.OnInit(userData);
//初始化界面,找到预制体的位置
itemPrefab = transform.Find("bg/Scroll View/Viewport/Item").gameObject;
//设置好Item父节点的位置
grid = transform.Find("bg/Scroll View/Viewport/Content");
}
protected override void OnOpen(object userData)
{
base.OnOpen(userData);
//在打开UI时候执行以下方法
InitSevenDayItems();
}
private void InitSevenDayItems()
{
//读表固定操作
IDataTable<DRSevenDayLogin> dtSevenDayLogins = GameEntry.DataTable.GetDataTable<DRSevenDayLogin>();
totalDays = dtSevenDayLogins.Count;//行数
//通过一个for循环来实例化具体行数
for (int i = 0; i < totalDays; i++)
{
//实例化预制体
GameObject item = Instantiate(itemPrefab);
//显示出来
item.SetActive(true);
//设置好父节点
item.transform.SetParent(grid);
//获取数据表行,第一行
DRSevenDayLogin dtSevenDayLogin = dtSevenDayLogins.GetDataRow(i + 1);
//给实例化出来的预制体添加一个脚本,就是下面写的那个类,并实现SetSevenDayItemInfo方法,传过去这一行的数据
item.AddComponent<SevenDayLoginItem>().SetSevenDayItemInfo(dtSevenDayLogin);
}
}
/// <summary>
/// 关闭按钮
/// </summary>
public void CloseBtn()
{
GameEntry.UI.OpenUIForm(UIFormId.GameoneForm, this);
Close(this);
}
/// <summary>
/// 当关闭的时候,删掉这些实例化,以免再次打开时候出错
/// </summary>
/// <param name="userData"></param>
protected override void OnClose(object userData)
{
base.OnClose(userData);
for (int i = 0; i < grid.childCount; i++)
{
Destroy(grid.GetChild(i).gameObject); //立即对对像进行销毁
}
}
}
/// <summary>
/// 给Item添加的脚本
/// </summary>
public class SevenDayLoginItem : MonoBehaviour
{
//展示文本
private Text des;
//item奖励图片模板
private GameObject itemImgPrefab;
/// <summary>
/// 父节点
/// </summary>
private Transform Imggrid;
private void Awake()
{
//得到展示文本,图片预制和图片父节点
des = transform.Find("miaoshuImg/miaoshuText").GetComponent<Text>();
itemImgPrefab = transform.Find("jiangliImg").gameObject;
Imggrid = transform.Find("jiangliGird");
}
public void SetSevenDayItemInfo(DRSevenDayLogin info)
{
//展示文本即是读表得到的AwardDescribe
des.text = info.AwardDescribe;
//用List来接一下截取字符串工具的成果
List<string> items = DataTableExtension.GetItemIdAndNumString(info.LoginAwardItems);
//截到几个就有几个图片,然后通过for循环来附上图片
for (int i = 0; i < items.Count; i++)
{
//实例化图片
GameObject itemImg = Instantiate(itemImgPrefab);
itemImg.SetActive(true);//显示
itemImg.transform.SetParent(Imggrid);//设置好父节点
//当List不为空的时候
if (items!=null)
{
//实例化的图片的sprite=传过来一个道具Id,得到资源(用井号分割ID和数量的List的第零位即ID)
itemImg.GetComponent<Image>().sprite = UIExtension.GetItemSprite(DataTableExtension.GetItemIdAndNum(items[i])[0]);
}
}
}
}
}
中间用到的几个工具的代码如下
DataTableExtension
/// <summary>
/// 用|分割表内数据
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public static List<string> GetItemIdAndNumString(string data)
{
if (!data.Contains("#")||!data.Contains("|"))
{
return null;
}
List<string> retList = new List<string>();
string[] items = data.Split(new char[] { '|' });
for (int i = 0; i < items.Length; i++)
{
retList.Add(items[i]);
}
return retList;
}
/// <summary>
/// 用#分割
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public static int[] GetItemIdAndNum(string data)
{
if (!data.Contains("#"))
{
return null;
}
int[] retArray = new int[2];
string[] item = data.Split(new char[] { '#' });
for (int i = 0; i < item.Length; i++)
{
retArray[0] = Convert.ToInt32(item[0]);
retArray[1] = Convert.ToInt32(item[1]);
}
return retArray;
}
UIExtension
/// <summary>
/// 传过来一个道具id Sprite
/// </summary>
/// <param name="ItemId"></param>
/// <returns></returns>
public static Sprite GetItemSprite(int ItemId)
{
IDataTable<DRUIItem> drItems = GameEntry.DataTable.GetDataTable<DRUIItem>();
DRUIItem drItem = drItems.GetDataRow(ItemId);
Sprite sprite = null;
if (sprite == null)
{
string path = drItem.PicPath + "/" + drItem.PicName;
sprite = Resources.Load<Sprite>(path);
if (sprite != null) return sprite;
}
if (sprite == null)
{
Debug.LogError("找不到" + drItem.PicPath + drItem.PicName + "文件");
}
return sprite;
}
好了,运行一下看下效果
就是这样咯,虽然很low,但是大体思路是这样滴