K-digital traning/유니티 심화

[주말과제]UGUI+데이터 연동(1)

내꺼블로그 2023. 9. 10. 22:51

*구현해야 되는 부분

 

 

 

 

 

 

 

 

 

 

1. 구조 잡기

 

 

 

 

 

 

 

 

 

 

 

 

2. scrollview test

 

(1)

 

UIMain 자식으로 UIPageShop이라는 gameObject를 생성.

그리고 그 자식으로 UIScrollview 이미지를 만들어 스크롤 영역(이미지를 보여주고자 하는 영역)을 잡고 content gameObject를 생성한 뒤 왼쪽 상단에 부착한다.

 

 

 

 

 

 

 

 

(2)

 

content gameObject에 Content Size Fitter 컴포넌트를 부착하고 Horizontal Fit과 Vertical Fit의 설정을 Preferred Size로 변경한다.

다음 UIGoldCell을 수평으로 정렬하기 위해 Horizontal Layout Group 컴포넌트를 부착한다.

 

 

 

 

 

 

 

 

(3)

 

UIGoldCell을 여러 개 만든 다음 content에 부착된 horizontal layout의 spacing 값을 조절하여 UI 구조를 잡아준다.

 

 

 

 

 

 

 

 

 

(4)

 

 

UIScrollview object에 scroll rect 컴포넌트를 부착한 뒤 content 속성에 content object를 할당한다.

그 뒤 설정해놓은 UIScrollview 부분의 이미지만 보이도록 하기 위해 Mask 컴포넌트도 부착한다.

실행했을 때 UIGoldCell이 제대로 다 보이면 성공

요로코롬이면 성공이당

 

 

 

 

 

 

 

 

 

 

 

 

3.UIGoldCell 구현하기

 

(1)

UIGoldCell을 구현하기 위해 위에서 UIScrollview 구조를 잡기 위해 만들어놓았던 UIGoldCell을 한 개만 남긴 채 전부 삭제한다.

작업을 수월하게 진행하기 위해 UIPageShop object를 비활성화하고 UIGoldCell을 UIPageShop 자식에서 꺼낸다.

 

 

 

 

 

(2)

 

UIGoldCell 제작에 필요한 리소스를 찾고 UIGoldCell의 구조를 잡는다.

 

 

 

 

 

(3)

 

UIGoldCell object를 prefab화 한 뒤 UIGoldCell을 Scene에서 제거한다.

 

 

 

 

 

 

 

 

 

 

4. 데이터 연동하기

 

(1)gold_data 엑셀 파일을 만든다.

 

 

 

 

(2)Excel 파일을 기반으로 Json 파일을 생성한다.

 

 

 

(3)  Project 창에 Resources 폴더를 생성하고 그 폴더에 gold_data.json 파일을 넣는다.

 

 

 

 

 

 

 

 

5. Atlas 제작

 

(1) 방금 만들어놓은 Resources 폴더에 Atlas 폴더를 만들고 GoldAtlas라는 이름의 Atlas를 생성한다.

 

 

(2) GoldAtlas를 클릭하고 inspector 창에 보이는 Objects for Packing 속성에 찾아놓은 gold icon들을 할당한다.

      또한 atlas를 생성할 때 Allow Rotation속성과 Tight Packing 속성의 체크를 해지한다.

 

그러면 다음과 같은 아틀라스가 생성된다.

 

 

 

 

 

 

 

 

 

 

6. 코드

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

public class DataManager
{
    public static readonly DataManager Instance = new DataManager();
    private Dictionary<int, GoldData> dicGoldDatas;
    public Dictionary<int, GoldData> DicGoldDatas { get { return dicGoldDatas; } }
    private DataManager() { }

    public void LoadData()
    {
        TextAsset textGoldData = Resources.Load<TextAsset>("data/gold_data");
        GoldData[] goldDatas = JsonConvert.DeserializeObject<GoldData[]>(textGoldData.text);
        this.dicGoldDatas = goldDatas.ToDictionary(x => x.id);
    }

    public GoldData GetGoldData(int id)
    {
        return this.dicGoldDatas[id];
    }

    public int GetGoldDataCount()
    {
        return this.dicGoldDatas.Count;
    }
}

 

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

public class GoldData
{
    public int id;
    public string name;
    public int type;
    public int value;
    public float price;
    public string icon_name;
    public float pos_x;
    public float pos_y;
}

 

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

public class AtlasManager
{
    public static readonly AtlasManager Instance = new AtlasManager();
    private SpriteAtlas goldIconAtlas;

    private AtlasManager()
    {
        
    }

    public void LoadAtlas()
    {
        this.goldIconAtlas = Resources.Load<SpriteAtlas>("atlas/GoldAtlas");
    }

    public Sprite GetGoldIconSprite(string icon_name)
    {
        return this.goldIconAtlas.GetSprite(icon_name);
    }
}

 

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

public class UIMain : MonoBehaviour
{
    [SerializeField]
    private UIPageShop uiPageShop;

    // Start is called before the first frame update
    void Start()
    {
        DataManager.Instance.LoadData();
        AtlasManager.Instance.LoadAtlas();
        this.uiPageShop.Init();
        this.uiPageShop.onClickPrice = (id) =>
        {
            GoldData data = DataManager.Instance.GetGoldData(id);
            Debug.LogFormat("<color=blue>{0} : {1}</color>", (UIGoldCell.eGoldType)data.type, data.price);
        };
    }
}

 

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

public class UIPageShop : MonoBehaviour
{
    [SerializeField]
    private UIScrollview uiScrollview;

    public System.Action<int> onClickPrice;
    public void Init()
    {
        uiScrollview.Init();
        uiScrollview.onClickPrice = (id) =>
        {
            GoldData data = DataManager.Instance.GetGoldData(id);
            Debug.LogFormat("<color=yellow>{0} : {1}</color>", (UIGoldCell.eGoldType)data.type, data.price);
            this.onClickPrice(data.id);
        };
    }
}

 

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

public class UIScrollview : MonoBehaviour
{
    [SerializeField]
    private GameObject uiGoldCellPrefab;

    [SerializeField]
    private Transform parent;

    private List<UIGoldCell> arrUIGoldCell = new List<UIGoldCell>();

    public System.Action<int> onClickPrice;
    public void Init()
    {
        foreach(GoldData goldData in DataManager.Instance.DicGoldDatas.Values)
        {
            GoldData data = goldData;
            GameObject uiGoldCellGo = Instantiate(uiGoldCellPrefab, parent);
            UIGoldCell uiGoldCell = uiGoldCellGo.GetComponent<UIGoldCell>();
            uiGoldCell.Init(data.id);
            arrUIGoldCell.Add(uiGoldCell);
            uiGoldCell.btnPrice.onClick.AddListener(() =>
            {
                Debug.LogFormat("{0} : {1}", (UIGoldCell.eGoldType)data.type, data.price);
                this.onClickPrice(data.id);
            });
        }
    }
}

 

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

public class UIGoldCell : MonoBehaviour
{
    public enum eGoldType
    {
        Tiny, Fistful, Pouch, Box, Chest, Vault
    }
    [SerializeField]
    private Image icon;
    [SerializeField]
    private TMP_Text txtName;
    [SerializeField]
    private TMP_Text txtValue;
    [SerializeField]
    private TMP_Text txtPrice;
    public Button btnPrice;

    private eGoldType type;
    private int id;
    public void Init(int id)
    {
        this.id = id;
        GoldData data = DataManager.Instance.GetGoldData(this.id);
        this.icon.sprite = AtlasManager.Instance.GetGoldIconSprite(data.icon_name);
        this.icon.SetNativeSize();
        this.icon.transform.localPosition = new Vector2(data.pos_x, data.pos_y);
        this.txtName.text = data.name;
        this.type = (eGoldType)data.type;
        this.txtValue.text = string.Format($"{data.value:#,##0} Gold");
        this.txtPrice.text = string.Format($"US ${data.price}");
    }
}

 

 

 

결과