[UGUI연습]-동적 스크롤 뷰, json연결
2023. 9. 7.

-Resources 폴더에 chest_data.json 추가

-newtonsoft Json 패키지 추가

-ChestData 클래스 추가

-DataManager 스크립트는 싱글톤으로 데이터를 관리한다.

UIChestScrollView.cs에 Init()메서드 추가
메인에서 호출/결과

=> json에서 데이터를 잘 가져오는 것을 로그로 확인했다.

 

이제 기존에 만들어둔 Cell을 지웠다. 지우기 전에 UIChestCellAd와 UIChestCell을 프리팹으로 만들어 두었다.

=> Data를 기반으로 프리팹 인스턴스를 생성하기 위해.(이 때 UIChestScrollview/content 자식으로 붙인다.

Data를 매개변수로 넘기도록 코드 수정

=> ScrollView의 Init에서 코드 수정. cell에 요소 하나의 데이터를 넘기기 위해 매개변수로 넣어줌

=> Cell 의 Init은 매개변수로 받은 데이터를 받는다.

 

UIChestCell의 Init 메서드에서는 Data를 기반으로 이름, 가격을 표시 한다

scrollView의 Init수정/ cell의 Init수정
cell의 Init 수정

이제 sprite를 추가하도록 코드를 수정하려 한다. 먼저 스프라이트가 필요하다. 아틀라스를 생성해 주었다.

아틀라스 생성

https://docs.unity3d.com/ScriptReference/U2D.SpriteAtlas.GetSprite.html

 

Unity - Scripting API: U2D.SpriteAtlas.GetSprite

Success! Thank you for helping us improve the quality of Unity Documentation. Although we cannot accept all submissions, we do read each suggested change from our users and will make updates where applicable. Close

docs.unity3d.com

-Atlas.GetSprite(string name)

cell

-cell에서 Atlas를 불러온 후 이미지에 GetSprite로 아틀라스에서 스프라이트를 이름으로 받아 넣어준다.

 

참고)

https://maintaining.tistory.com/entry/Unity-%EC%8A%A4%ED%94%84%EB%9D%BC%EC%9D%B4%ED%8A%B8-%EC%95%84%ED%8B%80%EB%9D%BC%EC%8A%A4Sprite-Atlas-%EC%82%AC%EC%9A%A9-%EB%B0%A9%EB%B2%95

 

[Unity] 스프라이트 아틀라스(Sprite Atlas) 사용 방법

1. 스프라이트 아틀라스(Sprite Atlas) 스프라이트 아틀라스는 여러 개의 텍스처를 단일 텍스처로 결합하는 에셋이다. 스프라이트 아틀라스를 사용하지 않고 여러 개의 스프라이트를 사용하면 스프

maintaining.tistory.com

 

 

sprite 동적으로 불러오기

-다만 아직 onclick하는 걸 정정 스크롤뷰에서 동적으로 코드 수정을 덜해서 하단의 버튼을 클릭하면 널 나온다. 수정필요!

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

public class ChestData 
{
    public int id;
    public string name;
    public int type;
    public int price;
    public string sprite_name;
  
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Newtonsoft.Json;
using System.IO;
public class DataManager 
{
    public static readonly DataManager Instance = new DataManager();
    private List<ChestData> chestDatas = new List<ChestData>();
    public void LoadChestData()
    {
        string json = File.ReadAllText("./Assets/Resources/chest_data.json");//파일 읽기
        // Debug.Log(json);
        this.chestDatas = JsonConvert.DeserializeObject<List<ChestData>>(json);//역직렬화

    }
    public List<ChestData> GetChestDatas()
    {
       return this.chestDatas;
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Test05Main : MonoBehaviour
{
    [SerializeField] UIChestScrollView chestScrollview;
    // Start is called before the first frame update
    void Start()
    {
        AtlasManager.instance.LoadAtlases();
        DataManager.Instance.LoadChestData();
        this.chestScrollview.Init();

    }

    // Update is called once per frame
    void Update()
    {
        
    }
}
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.U2D;

public class UIChestScrollView : MonoBehaviour
{
    private List<UIChestCell> cells = new List<UIChestCell>();
    
    [SerializeField] GameObject contentGo;
    [SerializeField] GameObject uiChestCellAdGo;//프리팹
    [SerializeField] GameObject uiChestCellGo;//프리팹
    void Start()
    {
        
        for (int i = 0; i < cells.Count; i++)
        {
            UIChestCell cell = cells[i];
            cell.onClickPrice = () => {
                Debug.LogFormat("<color=yellow>{0}, {1}</color>", cell.ChestType, cell.Price);
            };

            var chestType = (UIChestCell.eChestType)i;
            if (chestType == UIChestCell.eChestType.Wooden)
            {
                //var cellAd = (UIChestCellAd)cell;
                UIChestCellAd cellAd = cell as UIChestCellAd;
                cellAd.onClickAd = () =>
                {//cellAd에서 클릭 이벤트 발생하면 
                    Debug.LogFormat("<color=yellow>{0}, 광고보기</color>", cell.ChestType);
                };
            }

         
           // cell.Init();
        }
    }

    public void Init()
    {
        List<ChestData> data = DataManager.Instance.GetChestDatas();
        for(int i=0; i<data.Count; i++)
        {
          
            //Debug.LogFormat("{0} {1} {2} {3} {4}", data[i].id, data[i].name, data[i].type, data[i].price, data[i].sprite_name);
            if (data[i].id == 100)
            {
                GameObject go = Instantiate<GameObject>(this.uiChestCellAdGo, this.contentGo.transform);
                this.cells.Add(go.GetComponent<UIChestCell>());
                //sprite = this.atlas.GetAtlas(data[i].sprite_name);
                this.cells[i].Init(data[i]);//cell에 요소 하나의 데이터를 넘기기 위해 매개변수로 넣어줌.

            }
            else
            {
                GameObject go = Instantiate<GameObject>(this.uiChestCellGo, this.contentGo.transform);
                this.cells.Add(go.GetComponent<UIChestCell>());
                this.cells[i].Init(data[i]);
            }
        }
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.U2D;

public class AtlasManager : MonoBehaviour
{
    [SerializeField] private string[] arrAtlasNames;

    private Dictionary<string, SpriteAtlas> dicAtlases = new Dictionary<string, SpriteAtlas>();
    public static AtlasManager instance;

    private void Awake()
    {
        if (instance != null && instance != this)
        {
            Destroy(this);
            throw new System.Exception("An instance of this singleton already exists.");
        }
        else
        {
            instance = this;
        }

        DontDestroyOnLoad(this.gameObject);
    }

    public void LoadAtlases()
    {
        foreach (var atlasName in this.arrAtlasNames)
        {
            var atlas = Resources.Load<SpriteAtlas>(atlasName);
            this.dicAtlases.Add(atlasName, atlas);
        }

        Debug.LogFormat("{0}개의 아틀라스를 로드 했습니다. ", this.dicAtlases.Count);
    }

    public SpriteAtlas GetAtlas(string atlasName)
    {
        return this.dicAtlases[atlasName];
    }
  
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
using UnityEngine.U2D;

public class UIChestCell : MonoBehaviour
{
    [SerializeField] Image img;
   // [SerializeField] AtlasManager atlas;
    [SerializeField] TextMeshProUGUI textMeshPro;
    [SerializeField] TextMeshProUGUI textMeshPro2;
    public enum eChestType
    {
        Wooden, Silver, Golden, Epic, Legendary
    }

    [SerializeField] protected Button btnPrice;
    [SerializeField] protected eChestType chestType;
    [SerializeField] protected int price;
    public int Price => this.price;
    public System.Action onClickPrice;
    public eChestType ChestType
    {
        get
        {
            return this.chestType;
        }
    }
    public virtual void Init(ChestData data)
    {
        
        Debug.LogFormat("[UIChestCell] Init : {0}, name:{1}, price:{2}", this.chestType,data.name, data.price);
       
        var atlas = AtlasManager.instance.GetAtlas("chest");
        this.img.sprite = atlas.GetSprite(data.sprite_name);
        this.img.SetNativeSize();

        this.textMeshPro.text = data.name;
        //Debug.Log(this.textMeshPro[1].text);
        this.textMeshPro2.text = data.price.ToString();
        //this.chestType = data.name;
        this.btnPrice.onClick.AddListener(() => {
            Debug.LogFormat("{0}, {1}", this.chestType, this.price);
            this.onClickPrice();
        });
    }
}
using System.Collections;
using System.Collections.Generic;

using UnityEngine;
using UnityEngine.UI;

public class UIChestCellAd : UIChestCell
{
    [SerializeField]
    private Button btnAd;
    public System.Action onClickAd;

    private void Start()
    {

    }

    public override void Init(ChestData data)
    {
        //base.Init();
        base.Init(data);
        Debug.LogFormat("[UIChestCellAd] Init : {0}", this.chestType);
     
        this.btnAd.onClick.AddListener(() => {//버튼 클릭시
            Debug.LogFormat("{0}, 광고보기", this.chestType);
            this.onClickAd();//버튼이 클릭된 이벤트 발생
        });
    }
}
myoskin