유니티3D 프로그래밍

Unity UGUI 상점 창 구현 (21.04.23) 본문

Unity/수업내용

Unity UGUI 상점 창 구현 (21.04.23)

tjdgus9955 2021. 4. 23. 18:14

상점 UI 구현

 

 

Gold 탭과 Gem 탭을 클릭하면 각 탭에 해당하는 상품들을 보여준다.

 

오브젝트 구성요소

 

ScrollView 오브젝트 구성

 

Contents 오브젝트 구성

 

UIShopItem 프리펩 구성

 

각 상품의 이미지, 개수, 가격을 동적으로 변경할 수 있게 구성함.

 

사용한 스크립트 정보

 

ShopData : 상점에서 판매하는 제품들의 정보를 저장하는 스크립트

using UnityEngine;

public class ShopData 
{
    public int id;
    public int budget_type;
    public string name;
    public int amount;
    public int cost_type;
    public float cost;
    public int bonus;
    public string sprite_name;
}

ShopInfo : 데이터를 초기화하는 역할.

 

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

public class ShopInfo
{
    public int id;
    public int amount;
    public float cost;
    public int bonus;

    public ShopInfo(int id, int amount, float cost, int bonus)
    {
        this.id = id;
        this.amount = amount;
        this.cost = cost;
        this.bonus = bonus;
    }
}

UIListProduct : DataManager를 통해 Load한 상점 정보를 불러와서 변수에 저장한 후 ScrollviewTest를 통해 호출해서 프리펩을 생성할 때 데이터를 제공하는 역할 ex) 이미지, 텍스트 등

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

public class UIListProduct : MonoBehaviour
{
    public SpriteAtlas spriteAtlas;
    public Image shopProduct;
    public Text price;
    public Text getAmount;
    private ShopInfo info;
    public void Init(ShopInfo info)
    {
        this.info = info;
        var data = DataManager.GetInstance().dicShopDatas[this.info.id];
        this.getAmount.text = string.Format("{0:#,###}", data.amount);
        this.price.text = string.Format("{0}", data.cost);
        this.shopProduct.sprite = spriteAtlas.GetSprite(data.sprite_name);
    }
}

DataManager : Json 파일을 역직렬화를 통해 Dictionary에 저장함. instance를 통해 다른 스크립트에서 쉽게 접근이 가능하도록 함.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Newtonsoft.Json;
using System.Linq;
public class DataManager
{
    private static DataManager instance;
    public Dictionary<int, StageData> dicStageDatas;
    public Dictionary<int, RewardData> dicRewardDatas;
    public Dictionary<int, ItemData> dicItemDatas;
    public Dictionary<int, MissionData> dicMissionDatas;
    public Dictionary<int, MissionRewardData> dicMissionRewardDatas;
    public Dictionary<int, ShopData> dicShopDatas;

    //생성자 
    private DataManager()
    {

    }

    public static DataManager GetInstance()
    {
        if (DataManager.instance == null)
        {
            DataManager.instance = new DataManager();
        }
        return DataManager.instance;
    }
    public void LoadDatas()
    {
        

        var ta = Resources.Load<TextAsset>("Datas/mission_data");
        var json = ta.text;
        this.dicMissionDatas = JsonConvert.DeserializeObject<MissionData[]>(json).ToDictionary(x => x.id);

        ta = Resources.Load<TextAsset>("Datas/missionreward_data");
        json = ta.text;
        this.dicMissionRewardDatas = JsonConvert.DeserializeObject<MissionRewardData[]>(json).ToDictionary(x => x.id);

        ta = Resources.Load<TextAsset>("Datas/shop_data");
        json = ta.text;
        this.dicShopDatas = JsonConvert.DeserializeObject<ShopData[]>(json).ToDictionary(x => x.id);


        Debug.LogFormat("load completed!, {0}, {1}", this.dicMissionDatas.Count, this.dicMissionRewardDatas.Count);
    }
}

DeleteChild : 다른 탭을 눌러 다른 재화의 정보를 보려고 할 때 현재 탭의 contents의 하위 오브젝트들을 전부 삭제 한 뒤 클릭한 탭의 재화를 다시 출력하기 위해 오브젝트를 파괴하는 역할을 하는 스크립트

 

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

public class DeleteChild : MonoBehaviour
{
    public void DeleteChilds()
    {
        // child 에는 부모와 자식이 함께 설정 된다.
        var child = this.GetComponentsInChildren<Transform>();

        foreach (var iter in child)
        {
            // 부모(this.gameObject)는 삭제 하지 않기 위한 처리
            if (iter != this.transform)
            {
                Destroy(iter.gameObject);
            }
        }
    }
}

ScrollViewTest : 스크롤 뷰를 테스트 하기 위한 스크립트로 Coin 탭이 기본 화면이고 각각의 탭을 누를때 onClick을 호출한다. Button을 누르면 누른 탭의 이미지를 활성화하고 다른 탭들의 이미지를 비활성화 한다.

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

public class ScrollviewTest : MonoBehaviour
{
    public Button coinButton;
    public Button gemButton;
    public Button soulGemButton;
    public GameObject listItemPrefab;
    public Transform contents;
    public DeleteChild delete;
    void Start()
    {
        DataManager.GetInstance().LoadDatas();
        //foreach(var pair in DataManager.GetInstance().dicMissionDatas)
        //{
        //    var go = Instantiate<GameObject>(this.listItemPrefab, contents);
        //    var listItem = go.GetComponent<UIListItem>();
        //    var data = pair.Value;

        //    var info = new MissionInfo(data.id, 0, 0, 0);
        //    listItem.Init(info);
        //}

        CallProduct(100);

        coinButton.onClick.AddListener(() =>
        {

            delete.DeleteChilds();
            CallProduct(100);
            coinButton.transform.GetChild(1).gameObject.SetActive(true);
            gemButton.transform.GetChild(1).gameObject.SetActive(false);
            soulGemButton.transform.GetChild(1).gameObject.SetActive(false);
        });

        gemButton.onClick.AddListener(() =>
        {
            delete.DeleteChilds();
            CallProduct(101);
            coinButton.transform.GetChild(1).gameObject.SetActive(false);
            gemButton.transform.GetChild(1).gameObject.SetActive(true);
            soulGemButton.transform.GetChild(1).gameObject.SetActive(false);
        });
    }
    // Update is called once per frame
    void Update()
    {
        
    }

    public void CallProduct(int budgetNum)
    {
        foreach (var pair in DataManager.GetInstance().dicShopDatas)
        {
            if (pair.Value.budget_type == budgetNum)
            {
                var go = Instantiate<GameObject>(this.listItemPrefab, contents);
                var listProduct = go.GetComponent<UIListProduct>();
                var data = pair.Value;

                var info = new ShopInfo(data.id, 0, 0, 0);
                listProduct.Init(info);
            }
        }
    }
}