썸네일 만들기 + 데이터 관리
2023. 9. 3.

썸네일 만들기

-이미지 선택 - 외곽선이 잘 안따지면 허용치를 낮춰보자

-반전 선택 후 배경 삭제(마스크 만들기)

-다시 반전 선택 후 복사해서 새 레이어에 붙여넣기

 

가운데 사각형 부분을 선택해서 뚫어준다.

-흰 사각형의 레이어를 선택하고 ctrl을 누른상태로 사각형을 눌러 선택한다. 위 사진처럼 흰색 표시가있어야함

-그 상태에서 자르고 싶은 이미지를 누른 후 ctrl+X ctrl+V한다.

 

이미지들을 원하는 상태로 다 잘라준 뒤 폴더를 만들어 넣어주었다. Texture Type을 Sprite로 변형해줘야 쓸 수 있다.

 

데이터 관리를 하기 위해 엑셀로 데이터를 만든 후 json으로 변환해 저장하였다.

hero_data.json
0.00MB

https://gofogo.tistory.com/64

 

[unity/json]Newtonsoft Json 라이브러리 손쉽게 추가하는법(package manager 이용)

[unity/json]Newtonsoft Json 라이브러리 손쉽게 추가하는법(package manager 이용) [핵심] com.unity.nuget.newtonsoft-json [windows]->[package manager]로 이동 후 [add pakaage by name...] 선택 com.unity.nuget.newtonsoft-json 를 입력 후

gofogo.tistory.com

newtonsoft json 추가,hero_data.json, HeroData클래스 추가

hero_data.json을 Resources폴더안에 Data폴더를 만든 후 넣어준다.

데이터 관리를 위해 HeroData.cs를 만든 후 Scripts폴더에 넣어준다.

App.cs도 Scripts폴더에 추가한다. App.cs는 빈 오브젝트 App을 만든 후 넣어준다.

App.cs에 using Newtonsoft.Json추가 및 코드 작성/ 실행 후 로그 확인

HeroData.cs는 데이터 관련 스크립트 이므로 Scripts폴더에 Data폴더를 만들어 따로 넣어주었다.

-현재는 App이 데이터를 관리하는 모양새이다. 데이터를 더 깔끔하게 관리하기 위해 DataManager.cs를 새로 작성한다.

DataManager작성, App.cs수정

-DataManager가 딕셔너리를 통해 데이터를 관리하도록 코드를 추가한다.

딕셔너리에 추가 되었는지 로그로 확인

버튼 눌러서 Hero 만들기

App.cs의 Start부분 수정/Load Prefab수정

-LoadPrefab에서 버튼에 텍스트를 넣어준다.(prefabs의 순서대로 앞부터 넣어지게 하였다.)

-생성되고 나면 버튼을 더 눌러도 생성되지 않고 로그가 나온다.

버튼 눌러서 Hero 만들기 결과
Appcs. 하단의 CreateHero()메서드 생성 - 버튼에 id를 써서 가져오는 경우

 

-위의 내용은 단순한 버튼 클릭 후 생성이지만 코드를 수정해 이미지 버튼을 클릭하였을때 선택한 이미지 버튼에 해당하는 캐릭터를 불러오도록 구현하려 한다.

App.cs 수정

-data의 id를 Init에 매개변수로 넣어준다. 즉, herDatas에서 가져온 정보의 id가 전달된다.

UISlot.cs 생성

 

DataManager.cs수정

-HeroDatas() 메서드는 dictionary의 값을 List로 바꾸기 위해 사용한다. 이 때 Values이므로 값을 의미하며, 키를 쓰려고 했다면 Keys.ToList()와 같이 작성했을 것이다. 또한 using System.Linq를 써줘야한다.

https://learn.microsoft.com/ko-kr/dotnet/api/system.linq.enumerable.tolist?view=net-7.0 

 

Enumerable.ToList<TSource>(IEnumerable<TSource>) 메서드 (System.Linq)

IEnumerable<T>에서 List<T>을 만듭니다.

learn.microsoft.com

 

 

 

실행하면 이미지가 변경되고, 이미지를 클릭하면 해당하는 id를 로그로 출력

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

public class HeroInfo
{
    public int id;
    public float hp;
    public float damage;

    //생성자 
    public HeroInfo(int id, float hp, float damage)
    {
        this.id = id;
        this.hp = hp;
        this.damage = damage;
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Hero : MonoBehaviour
{
    private HeroInfo info;
    private GameObject model;
    public void Init(HeroInfo info, GameObject model)
    {
        this.info = info;
        this.model = model;

        Debug.LogFormat("Init: {0}, {1}", this.info, this.model);
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class UISlot : MonoBehaviour
{
    private int id;
    public System.Action<int> onClick;
    [SerializeField]
    private Button btn;
    [SerializeField]
    private Image img;

    public void Init(int id, Sprite sp)
    {
        this.id = id;

        //sprite_name
        //atals 
        img.sprite = sp;

        this.btn.onClick.AddListener(() => {
            this.onClick(this.id);
        });
    }


    // Update is called once per frame
    void Update()
    {
        
    }
}
using Newtonsoft.Json;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Linq;
public class DataManager
{
    public static readonly DataManager instance = new DataManager();
    private Dictionary<int, HeroData> dicHeroDatas = new Dictionary<int, HeroData>();
    //생성자 
    private DataManager()
    {
    }

    public void LoadHeroData()
    {
        TextAsset asset = Resources.Load<TextAsset>("Data/hero_data");
        Debug.Log(asset.text);  //json 문자열 

        //역직렬화 
        HeroData[] heroDatas = JsonConvert.DeserializeObject<HeroData[]>(asset.text);
        foreach (HeroData data in heroDatas)
        {
            Debug.LogFormat("{0} {1} {2} {3} {4} {5}", data.id, data.name, data.max_hp, data.damage, data.prefab_name, data.sprite_name);
            this.dicHeroDatas.Add(data.id, data);   //사전에 추가 
        }
        Debug.LogFormat("HeroData 로드 완료 : {0}", this.dicHeroDatas.Count);
    }

    public List<string> GetHeroPrefabNames()
    {
        List<string> list = new List<string>();
        foreach (HeroData data in this.dicHeroDatas.Values)
        {
            list.Add(data.prefab_name);//HeroData의 prefab_name을 리스트에 추가
        }
       // Debug.Log(list.Count);
        return list;
    }

    public HeroData GetHeroData(int id)
    {
        return this.dicHeroDatas[id];
    }

    public List<HeroData> HeroDatas()
    {
        return this.dicHeroDatas.Values.ToList();//using System.Linq; 추가해야함
    }
}
using Newtonsoft.Json;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class HeroData
{
    public int id;
    public string name;
    public float max_hp;
    public float damage;
    public string prefab_name;
    public string sprite_name;
}
using Newtonsoft.Json;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Newtonsoft.Json;  //네임 스페이스 추가 
using UnityEngine.UI;
using System.IO;
using UnityEngine.U2D;

public class App : MonoBehaviour
{
    [SerializeField] List<Button> buttons;//버튼들의 리스트 
    private List<GameObject> prefabs = new List<GameObject>();//프리팹이 저장될 변수
    [SerializeField] private Image thumb;
    [SerializeField] private SpriteAtlas atlas;

    [SerializeField]
    private UISlot[] uiSlots;
    private GameObject go;
    private int index;
    [SerializeField]private Text text;
    private string button_name;
    private bool isCreated;

    void Start()
    {      
        DataManager.instance.LoadHeroData();
        this.LoadPrefabs();//프리팹 리소스 로드


        //슬롯 초기화 
        List<HeroData> heroDatas = DataManager.instance.HeroDatas();
        for (int i = 0; i < heroDatas.Count; i++)
        {
            UISlot slot = this.uiSlots[i];
            HeroData data = heroDatas[i];
            Sprite sp = this.atlas.GetSprite(data.sprite_name);
            slot.onClick = (id) => {
                Debug.Log(id);
                this.CreateHero(id);
            };
            slot.Init(data.id, sp);
        }
        //foreach (Button btn in this.buttons)
        //{
        //    // Debug.Log(this.prefabs[j]);
        //    btn.onClick.AddListener(() =>
        //    {//버튼 클릭시               
        //        this.button_name = btn.GetComponentInChildren<Text>().text;//클릭한 버튼의 텍스트를 멤버 변수에 넣음
        //        for (int i = 0; i < prefabs.Count; i++)//프리팹 리스트를 돈다
        //        {
        //            if (this.prefabs[i].name == this.button_name)//프리팹의 객체와 버튼의 text가 같으면
        //            {
        //                this.go = this.prefabs[i];//gameobject에 프리팹 리스트의 요소를 넣음
        //            }
        //         }

        //        if (this.isCreated)
        //        {
        //            Debug.Log("이미 생성되었습니다. \n 더 이상 생성할 수 없습니다.");
        //        }
        //        else
        //        {
        //            // Debug.Log(this.go);
        //            GameObject createGo = new GameObject();

        //            // this.CreatePrefab(this.go);
        //            GameObject newGo = Instantiate<GameObject>(this.go, createGo.transform);
        //            Debug.Log(newGo.name);
        //            createGo.name ="Hero";
        //            this.isCreated = true;
        //        }
        //    });

        //}     
    }
    private void CreateHero(int id)
    {
        //Info만들기 
        //신규유저일경우 새로운 HeroInfo객체를 만들고 hero_info.json파일로 저장 
        //기존유저일경우 hero_info.json파일을 로드해서 역직렬화 해서 HeroInfo객체를 만든다 

        //저장위치 
        //Application.persistentDataPath

        string filePath = string.Format("{0}/hero_info.json", Application.persistentDataPath);
        //C:/Users/user/AppData/LocalLow/DefaultCompany/SaveAndLoad/hero_info.json
        Debug.Log(filePath);

        HeroInfo heroInfo = null;   //변수 정의 

        if (File.Exists(filePath))
        {
            //있다 (기존유저)
            Debug.Log("기존유저");
            //파일로드후 역직렬화 
        }
        else
        {
            //없다 (신규유저)
            Debug.Log("신규유저");
            HeroData heroData = DataManager.instance.GetHeroData(id);
            heroInfo = new HeroInfo(heroData.id, heroData.max_hp, heroData.damage);
        }


        int index = id - 100;
        Debug.LogFormat("index: {0}", index);
        GameObject prefab = this.prefabs[index];
        Debug.Log(prefab);
        GameObject heroGo = new GameObject();
        heroGo.name = "Hero";
        GameObject model = Instantiate<GameObject>(prefab, heroGo.transform);

        Hero hero = heroGo.AddComponent<Hero>();
        //HeroController 컴포넌트에 model과 info를 넘겨야 함 
        hero.Init(heroInfo, model);

    }
    private void LoadPrefabs()
    {
        List<string> heroPrefabNames = DataManager.instance.GetHeroPrefabNames();
    
        for(int i=0; i<heroPrefabNames.Count;i++) 
        {
            string path = string.Format("Prefabs/{0}", heroPrefabNames[i]);
            Debug.Log(path);        
            GameObject prefab1 = Resources.Load<GameObject>(path);//Resources 하위의 경로로 접근
            this.prefabs.Add(prefab1);
            for (int j = 0; j < buttons.Count; j++)
            {
                Text text = buttons[j].GetComponentInChildren<Text>();               
                if (i == j)
                {//버튼에 텍스트 넣어주기
                    text.text = this.prefabs[i].name;                 
                }
            }
        
        }
        
        Debug.LogFormat("프리팹들이 로드 되었습니다. count: {0}", this.prefabs.Count);
    }

 
}
myoskin