EasyCastleUNITY

유니티 GUI (스크롤 뷰 및 셀) 및 데이터 연동 본문

유니티 심화

유니티 GUI (스크롤 뷰 및 셀) 및 데이터 연동

EasyCastleT 2023. 9. 7. 12:25

스크롤뷰 인스펙터
content 스크롤뷰
cell 인스펙터

정적 스크롤 뷰 -> 많이 사용되므로 여러번 만들어 보기

 

버튼 이벤트 추가 

Cell의 종류는 2개, 기본 셀과 광고 셀로 나뉜다. 

기본 셀의 스크립트를 상속 받아 광고 셀 스크립트를 만든다.

이러한 셀들을 스크롤뷰에서 관리한다. 

UIChestCell

using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

public class UIChestCell : MonoBehaviour
{
    public enum eChestType
    {
        Wooden,Sliver,Golden,Epic,Legendary
    }

    public System.Action onBuyButtonClick;

    [SerializeField]
    protected eChestType chestType;
    [SerializeField]
    protected Button btnBuy;
    [SerializeField]
    protected int price;

    public eChestType ChestType => chestType;
    public int Price => price;
    
    public virtual void Init()
    {
        this.btnBuy.onClick.AddListener(() => {
            this.onBuyButtonClick();
            Debug.LogFormat("상자 타입:{0}, 가격:{1}",this.chestType,this.price);
        });
        
        
    }
}

UIChestCellAd

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class UIChestCellAd : UIChestCell
{
    [SerializeField]
    private Button btnAd;

    public System.Action onAdButtonClick;
    public override void Init()
    {
        base.Init();
        btnAd.onClick.AddListener(() => {
            this.onAdButtonClick();
            Debug.LogFormat("광고버튼 눌림");
        });
    }
}

UIChestScrollview

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class UIChestScrollview : MonoBehaviour
{
    [SerializeField]
    private UIChestCell[] arrCell;
    // Start is called before the first frame update
    void Start()
    {
        foreach (var cell in arrCell)
        {
            cell.Init();

            cell.onBuyButtonClick = () => {
                Debug.LogFormat("<color=yellow>상자 타입:{0}, 가격:{1} </color>",
                    cell.ChestType,cell.Price);
            };

            /// 방법1 

            //UIChestCellAd cellAd = cell as UIChestCellAd;
            //if(cellAd != null)
            //{
            //    cellAd.onAdButtonClick = () =>
            //    {
            //        Debug.Log("<color=yellow>광고 버튼 눌림</color>");
            //    };
            //}

            /// 방법2
            if (cell.ChestType == UIChestCell.eChestType.Wooden)
            {
                UIChestCellAd cellAd1 = cell as UIChestCellAd;
                cellAd1.onAdButtonClick = () =>
                {
                    Debug.Log("<color=yellow>광고 버튼 눌림</color>");
                };
            }
            //cellAd.onAdButtonClick = () => {
            //    Debug.Log("<color=yellow>광고 버튼 눌림</color>");
            //};
        }
    }
}

노란색 결과는 ScrollView에서 출력

흰색 결과는 자체적인 스크립트에서 출력

데이터 연동

정보 테이블

chest_data.json ->해당 파일을 Resources에 저장하고 불러오는 방식을 사용 

[
  {
    "id": "100",
    "name": "Wooden Chest",
    "type": "0",
    "price": "100",
    "sprite_name": "shop_img_chest_close_m_00"
  },
  {
    "id": "101",
    "name": "Sliver Chest",
    "type": "1",
    "price": "500",
    "sprite_name": "shop_img_chest_close_m_01"
  },
  {
    "id": "102",
    "name": "Golden Chest",
    "type": "2",
    "price": "1000",
    "sprite_name": "shop_img_chest_close_m_02"
  },
  {
    "id": "103",
    "name": "Epic Chest",
    "type": "3",
    "price": "1500",
    "sprite_name": "shop_img_chest_close_m_03"
  },
  {
    "id": "104",
    "name": "Legendary Chest",
    "type": "4",
    "price": "6500",
    "sprite_name": "shop_img_chest_close_m_04"
  }
]

DataManager

using Newtonsoft.Json;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;

public class DataManager 
{
    
    public static readonly DataManager instance = new DataManager(); //싱글톤 
    //정보를 저장할 사전 
    private Dictionary<int, ChestData> chestDataDics = new Dictionary<int, ChestData>();

    //생성자
    private void DataManger()
    {

    }

    public void LoadChestDatas()
    {
        TextAsset aseet = Resources.Load<TextAsset>("chest_data"); //json은 안 붙임

        //역직렬화
        ChestData[] chestDatas = JsonConvert.DeserializeObject<ChestData[]>(aseet.text);
        foreach(var chestData in chestDatas)
        {
            this.chestDataDics.Add(chestData.id, chestData);
        }
        Debug.Log("로드 완료");
    }

    public List<ChestData> GetChestDatas()
    {
        return this.chestDataDics.Values.ToList();
    }
}

ChestData -> 데이터 저장용 클래스

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ChestData 
{
    //  id    name    type    price   sprite_name 
    //int  string    int      int     stirng
    public int id;
    public string name;
    public int type;
    public int price;
    public string sprite_name;

}

UIChestScrollview

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class UIChestScrollview : MonoBehaviour
{
    [SerializeField]
    private UIChestCell[] arrCell;
    // Start is called before the first frame update

    public void Init()
    {
        //정보 불러오기 
        List<ChestData> chestDatas = DataManager.instance.GetChestDatas();
        foreach (var chestData in chestDatas)
        {
            Debug.LogFormat("<color=yellow>{0} {1} {2} {3} {4}</color>",
                chestData.id, chestData.name, chestData.type, chestData.price, chestData.sprite_name);
        }
    }
}

Main

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Test05Main : MonoBehaviour
{
    [SerializeField]
    private UIChestScrollview chestScrollview;
    void Start()
    {
        DataManager.instance.LoadChestDatas();
        this.chestScrollview.Init();
    }
}

로드 성공

데이터 연동 최종

데이터 테이블

chest_data.json 

[
  {
    "id": "100",
    "name": "Wooden Chest",
    "type": "0",
    "price": "100",
    "sprite_name": "shop_img_chest_close_m_00",
    "width": "306",
    "height": "282"
  },
  {
    "id": "101",
    "name": "Sliver Chest",
    "type": "1",
    "price": "500",
    "sprite_name": "shop_img_chest_close_m_01",
    "width": "332",
    "height": "289"
  },
  {
    "id": "102",
    "name": "Golden Chest",
    "type": "2",
    "price": "1000",
    "sprite_name": "shop_img_chest_close_m_02",
    "width": "334",
    "height": "330"
  },
  {
    "id": "103",
    "name": "Epic Chest",
    "type": "3",
    "price": "1500",
    "sprite_name": "shop_img_chest_close_m_03",
    "width": "330",
    "height": "342"
  },
  {
    "id": "104",
    "name": "Legendary Chest",
    "type": "4",
    "price": "6500",
    "sprite_name": "shop_img_chest_close_m_04",
    "width": "383",
    "height": "357"
  }
]

이미지 변화용 Sprite Atlas

DataManager

using Newtonsoft.Json;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;

public class DataManager 
{
    
    public static readonly DataManager instance = new DataManager(); //싱글톤 
    //정보를 저장할 사전 
    private Dictionary<int, ChestData> chestDataDics = new Dictionary<int, ChestData>();

    //생성자
    private void DataManger()
    {

    }

    public void LoadChestDatas()
    {
        TextAsset aseet = Resources.Load<TextAsset>("chest_data"); //json은 안 붙임

        //역직렬화
        ChestData[] chestDatas = JsonConvert.DeserializeObject<ChestData[]>(aseet.text);
        foreach(var chestData in chestDatas)
        {
            this.chestDataDics.Add(chestData.id, chestData);
        }
        Debug.Log("로드 완료");
    }

    public List<ChestData> GetChestDatas()
    {
        return this.chestDataDics.Values.ToList();
    }
}

ChestData 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ChestData 
{
    //  id    name    type    price   sprite_name  width  height
    //int  string    int      int     stirng       int    int
    public int id;
    public string name;
    public int type;
    public int price;
    public string sprite_name;
    public int width;
    public int height;
}

UIChestScrollview

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.U2D;

public class UIChestScrollview : MonoBehaviour
{

    [SerializeField]
    GameObject cellPrefab;
    [SerializeField]
    GameObject cellAdPrefab;
    [SerializeField]
    private GameObject context;
    [SerializeField]
    private SpriteAtlas atlas;
    // Start is called before the first frame update

    public void Init()
    {
        //정보 불러오기 
        List<ChestData> chestDatas = DataManager.instance.GetChestDatas();
        foreach (var chestData in chestDatas)
        {
            Debug.LogFormat("<color=yellow>{0} {1} {2} {3} {4}</color>",
                chestData.id, chestData.name, chestData.type, chestData.price, chestData.sprite_name);
            if (chestData.type == 0)
            {
                //인스턴스화
                GameObject go = Instantiate(cellAdPrefab, this.context.transform);
                //정보 저장
                UIChestCellAd chestAd = go.GetComponent<UIChestCellAd>();
                this.SetChestCellInfo(chestAd, chestData);

                chestAd.Init(); //초기화

                //대리자 액션 연결
                chestAd.onBuyButtonClick = () =>
                {
                    Debug.LogFormat("<color=yellow>상자 타입:{0}, 가격:{1} </color>",
                    chestAd.ChestType, chestAd.Price);
                };

                chestAd.onAdButtonClick = () =>
                {
                    Debug.Log("<color=yellow>광고 버튼 눌림</color>");
                };
            }
            else
            {
                //인스턴스화
                GameObject go = Instantiate(this.cellPrefab, this.context.transform);
                //정보 저장
                UIChestCell chest = go.GetComponent<UIChestCell>();
                this.SetChestCellInfo(chest, chestData);

                chest.Init(); //초기화

                //대리자 액션 연결
                chest.onBuyButtonClick = () =>
                {
                    Debug.LogFormat("<color=yellow>상자 타입:{0}, 가격:{1} </color>",
                    chest.ChestType, chest.Price);
                };
            }
        }
    }

    private void SetChestCellInfo(UIChestCell cell ,ChestData chestData)
    {
        cell.Cname = chestData.name;
        cell.ChestType = (UIChestCell.eChestType)chestData.type;
        cell.Price = chestData.price;
        cell.Id = chestData.id;
        cell.SpriteName = chestData.sprite_name;
        cell.Sprite = this.atlas.GetSprite(chestData.sprite_name);
        cell.Width = chestData.width;
        cell.Height = chestData.height;
    }
}

UIChestCellAd

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class UIChestCellAd : UIChestCell
{
    [SerializeField]
    private Button btnAd;

    public System.Action onAdButtonClick;
    public override void Init()
    {
        base.Init();
        btnAd.onClick.AddListener(() => {
            this.onAdButtonClick();
            Debug.LogFormat("광고버튼 눌림");
        });
    }
}

UIChestCell -> Cell 각각의 정보를 가지고 있다. 

using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

public class UIChestCell : MonoBehaviour
{
    public enum eChestType
    {
        Wooden,Sliver,Golden,Epic,Legendary
    }

    public System.Action onBuyButtonClick;


    protected eChestType chestType;
    [SerializeField]
    protected Button btnBuy;

    protected int price;

    protected int id;

    [SerializeField]
    protected string spriteName;

    protected string cname;

    //바꾸어야 하는 거, 가격하고 이름, 이미지
    [SerializeField]
    protected TMP_Text txtPrice;
    [SerializeField]
    protected TMP_Text txtName;
    [SerializeField] protected Image image;

    private Sprite sprite;

    private int width;
    public int Width
    {
        get { return width; } 
        set { width = value; }
    }
    private int height;
    public int Height
    {
        get { return height; }
        set { height = value; }
    }

    public Sprite Sprite
    {
        get { return sprite; }
        set { sprite = value; }
    }

    public int Id
    {
        get { return id; }
        set { id = value; }
    }
    public eChestType ChestType
    {
        get { return chestType; }
        set { chestType = value; }
    }
    public int Price
    {
        get { return price; }
        set { price = value; }
    }

    public string SpriteName
    {
        get { return spriteName; }
        set {  spriteName = value; }
    }
    
    public string Cname
    {
        get { return cname; }
        set {  cname = value; }
    }

    public virtual void Init()
    {
        //가격 및 이름의 Text 변경 
        this.txtPrice.text = this.price.ToString();
        this.txtName.text = this.cname.ToString();
        //이미지 설정 
        this.SetImage(this.image);
        this.btnBuy.onClick.AddListener(() => {
            this.onBuyButtonClick();
            Debug.LogFormat("상자 타입:{0}, 가격:{1}",this.chestType,this.price);
        });
    }

    private void SetImage(Image image)
    {
        image.sprite = this.sprite;
        image.SetNativeSize();
        //이미지 사이즈 변경 
        image.rectTransform.sizeDelta = new Vector2(this.width, this.height); 
    }
}

데이터 연동을 한 이후의 실행영상

만약 사이즈 조정을 하지 않으면 나오는 결과

사이즈가 제각각이다.
사이즈는 이렇게 조정하였다.

 

'유니티 심화' 카테고리의 다른 글

보석 상점 GUI  (0) 2023.09.09
골드 상점 GUI  (0) 2023.09.09
유니티 GUI 3 (Stage UI)  (0) 2023.09.06
유니티 GUI 2  (0) 2023.09.05
유니티 GUI  (0) 2023.09.04