1. 程式人生 > >Unity 常用網格佈局GridLayoutGroup使用方法一

Unity 常用網格佈局GridLayoutGroup使用方法一

       本文簡介:①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);
            }
        }
    }

}