本文简介:①UGUI GridLayoutGroup 的使用方法。
在游戏中,网格布局很是常见,比如背包,邮件商城等的展示,甚至是地图都可以使用到。GridLayoutGroup是UGUI封装的布局脚本,使用比较简单,但是范围很局限。适合用于子节点数量不是很多、结构单一的布局,比如简单背包。如下图
缺点:当子节点数据特别多的时候使用这种方法会很消耗资源,这种情况下需要考虑循环列表的使用。当结构功能复杂的布局也不能使用这种布局。
实现方法:
第一步:拼出背包界面UI,挂载对应的封装组件。 如下图
ScrollRect1:上需要挂载ScrollRect组件,Mask2d组件
Grid:上需要挂载GridLayoutGroup,并设置其属性。添加ContentSizeFilter(自适应位置)
第二步:代码实现
实现这个功能的三个脚本,ItemCell1是挂载在图2的Item上,GridShowType1挂载在图2的ScrollRect1上。这样的命名很孬孬孬。直接贴代码吧
GridShowType1:背包主脚本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Good {
public string icon;
public int num;
}
public class GridShowType1 : MonoBehaviour {
public GridLayoutGroup m_Grid;
public GameObject m_Item; //单元格对象//
private List<Good> m_Items;
void Start() {
SimulateData();
Init();
}
//模拟背包数据//
private void SimulateData() {
int simulateNum = 50;
if(m_Items == null)
m_Items = new List<Good>();
m_Items.Clear();
for(int i = 0; i < simulateNum; i++) {
Good good = new Good();
good.icon = "";
m_Items.Add(good);
}
}
public void Init() {
//初始化背包数据//
GameUtility.SetList<ItemCell1>(m_Items.Count, m_Grid.transform, m_Item, (a, b) => {
ItemCell1 cell = a as ItemCell1;
int tempi = b;
cell.SetCell(m_Items[tempi]);
}, true);
}
}
ItemCell1:背包单元格脚本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class ItemCell1 : MonoBehaviour {
public Image m_Bg;
public Image m_Icon;
//填充背包单元格的数据//
public void SetCell(Good good) {
m_Icon.sprite.name = good.icon;
}
}
GameUtility:封装公用方法集
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public static class GameUtility {
public delegate void UGUISetListDelegate<T>(T a, int b) where T : Component;
public static void AddChildToTarget(this Transform target, Transform child, bool issettran = true) {
if(child == null) {
return;
}
child.SetParent(target, false);
if(issettran) {
child.localScale = Vector3.one;
child.localPosition = Vector3.zero;
child.localEulerAngles = Vector3.zero;
}
}
public static void SetActive(this Component _tran, bool active) {
if(_tran == null)
return;
if(_tran.gameObject.activeSelf == active)
return;
_tran.gameObject.SetActive(active);
}
public static void SetList<T>(int prefabcount, Transform parentTrans, GameObject itemPrefab, UGUISetListDelegate<T> callback, bool adaptNum = true) where T : Component {
if(adaptNum) {
for(int i = prefabcount; i < parentTrans.childCount; i++) {
parentTrans.transform.GetChild(i).SetActive(false);
}
}
for(int i = 0; i < prefabcount; i++) {
int tempi = i;
T cell = default(T);
if(tempi < parentTrans.childCount) {
cell = parentTrans.transform.GetChild(tempi).GetComponent<T>();
} else {
GameObject go = GameObject.Instantiate(itemPrefab) as GameObject;
parentTrans.transform.AddChildToTarget(go.transform);
cell = go.transform.GetComponent<T>();
}
if(cell == default(T) || cell == null)
return;
cell.SetActive(true);
if(callback != null) {
callback(cell, tempi);
}
}
}
}