1. 처음 씬 시작 전 화면
2. 씬 시작
3. 2번째 슬롯을 눌렀을 시, hero_info 생성, 나머지 슬롯들은 자물쇠(lock)로 변경 및 hero 생성 불가
4. 기존 유저로 생성 되는 모습 확인
5. 완성 장면

 

[구현 목록]

1. 씬 실행시 HeroData를 로드한 뒤, 빈 slot의 thump(이미지)에 HeroData의 Sprite_name을 통해 Atlas의 sprite 를 불러와 각 slot의 thump에 적용

2. Application.persistentDataPath

(기본주소 = C:/Users/user/AppData/LocalLow/DefaultCompany/SaveAndLoad/hero_info.json)의 위치에 hero_info.json이 없다면 신규유저, 있다면 기존유저 판단.

3. 신규 유저라면 처음 slot들은 모두 오픈(캐릭터 이미지로 적용)되어 있으며, 슬롯 클릭시 클릭된 슬롯 제외한 나머지 슬롯 lock(자물쇠)로 변경 및 생성 불가.

4. 기존 유저라면 hero_info에 저장되어있는 id를 제외한 나머지 슬롯들은 모두 lock(자물쇠)으로 sprite 변경 및 생성 불가

5. hero가 없다면 슬롯 클릭시 생성, hero가 있다면 슬롯  클릭시 제거

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Newtonsoft.Json;  //네임 스페이스 추가 
using UnityEngine.UI;
using System;
using System.IO;
using UnityEngine.U2D;

public class AppMain : MonoBehaviour
{

    //프리팹이 저장될 변수 
    private List<GameObject> prefabs = new List<GameObject>();

    [SerializeField]
    private Button[] btns; //버튼 배열 인스턴스 선언

    [SerializeField]
    private Image thumb;

    [SerializeField]
    private SpriteAtlas atlas;

    [SerializeField]
    private UISlot[] uiSlots;

    private GameObject currentHero;  // 현재 존재하는 영웅 참조

    void Start()
    {
        DataManager.instance.LoadHeroData();
        LoadPrefabs();

        string filePath = string.Format("{0}/hero_info.json", Application.persistentDataPath);

        if (File.Exists(filePath)) // 기존 유저
        {
            string jsonData = File.ReadAllText(filePath);
            HeroInfo heroInfo = JsonConvert.DeserializeObject<HeroInfo>(jsonData);
            InitializeSlotsForExistingUser(heroInfo.id);
        }
        else // 신규 유저
        {
            InitializeSlotsForNewUser();
        }
    }

    void InitializeSlotsForExistingUser(int unlockedHeroId)
    {
        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;

            if (data.id == unlockedHeroId)
            {
                sp = this.atlas.GetSprite(data.sprite_name);
            }
            else
            {
                sp = this.atlas.GetSprite("lock");
                slot.isLocked = true;
            }

            slot.Init(data.id, sp);
            slot.onClick = (id) => { if (!slot.isLocked) CreateHero(id); };
        }
    }

    void InitializeSlotsForNewUser()
    {
        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.Init(data.id, sp);
            slot.onClick = (id) =>
            {
                if (!slot.isLocked) // 잠긴 슬롯을 클릭시 hero 생성 x
                {
                    CreateHero(id);
                    LockAllSlotsExcept(id);
                }
            };
        }
    }

    void LockAllSlotsExcept(int unlockedHeroId)
    {
        foreach (UISlot slot in this.uiSlots)
        {
            if (slot.id != unlockedHeroId)
            {
                slot.img.sprite = this.atlas.GetSprite("lock");
                slot.isLocked = true;
            }
        }
    }
    private void CreateHero(int id)
    {
        if (currentHero != null)
        {
            Destroy(currentHero);  // 이미 존재하는 영웅 삭제
            currentHero = null;
            return;
        }

        string filePath = string.Format("{0}/hero_info.json", Application.persistentDataPath);

        Debug.Log(filePath);

        HeroInfo heroInfo = null; //변수 정의 

        if (File.Exists(filePath)) //있다 (기존유저)
        {
            Debug.Log("<color=red>기존유저</color>");
            // 파일 로드 후 역직렬화, HeroInfo 객체 생성
            string jsonData = File.ReadAllText(filePath);
            heroInfo = JsonConvert.DeserializeObject<HeroInfo>(jsonData);



        }
        else //없다 (신규유저)
        {
            Debug.Log("<color=green>신규유저</color>");
            HeroData heroData = DataManager.instance.GetHeroData(id);
            heroInfo = new HeroInfo(heroData.id, heroData.max_hp, heroData.damage);

            // 생성된 HeroInfo 객체를 직렬화하여 JSON 파일로 저장
            string jsonData = JsonConvert.SerializeObject(heroInfo);
            File.WriteAllText(filePath, jsonData);
        }




        int index = id - 100;
        Debug.LogFormat("index: {0}", index);
        GameObject prefab = this.prefabs[index];
        Debug.Log(prefab);
        GameObject heroGo = new GameObject();
        heroGo.name = "Hero";
        currentHero = heroGo;
        GameObject model = Instantiate<GameObject>(prefab, heroGo.transform); // model은 heroGo의 자식객체로 인스턴스화

        Hero hero = heroGo.AddComponent<Hero>();

        hero.Init(heroInfo, model); //Hero 컴포넌트에 model과 info를 넘김




    }

    private void LoadPrefabs()
    {
        List<string> heroPrefabNames = DataManager.instance.GetHeroPrefabNames();

        foreach (string prefabName in heroPrefabNames)
        {
            string path = string.Format("Prefabs/{0}", prefabName);
            Debug.Log(path);
            GameObject prefab = Resources.Load<GameObject>(path);
            this.prefabs.Add(prefab);
        }
        Debug.LogFormat("프리팹들이 로드 되었습니다. count: {0}", this.prefabs.Count);
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class UISlot : MonoBehaviour
{
    public int id;
    public System.Action<int> onClick;
    [SerializeField]
    private Button btn;
   
    public Image img;
    public bool isLocked = false;  // 잠금 상태를 판별할 변수
    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 System.Linq;
using UnityEngine;


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"); //Unity의 Resources 폴더에서 파일을 로드
        Debug.Log(asset.text); //JSON 형식의 문자열을 확인


        HeroData[] heroDatas = JsonConvert.DeserializeObject<HeroData[]>(asset.text); //JSON 문자열을 HeroData[] 타입으로 역직렬화

        foreach (HeroData data in heroDatas) //역직렬화된 HeroData 객체들의 정보를 순회하며 출력
        {
            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); //Dictionary에 추가
            Debug.LogFormat("data.sprite_name = {0}",data.sprite_name);
        }
        Debug.LogFormat("<color=red> HeroData 로드완료 : {0} </color>", this.dicHeroDatas.Count); //빨간색으로 로그 호출
    }

    public List<string> GetHeroPrefabNames() //prafab의 이름을 저장한 리스트 가져오기
    {
        List<string> list = new List<string>();
        foreach (HeroData data in this.dicHeroDatas.Values) 
        {
            list.Add(data.prefab_name);
        }
        return list;
    }

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

    public List<HeroData> HeroDatas()
    {
        return this.dicHeroDatas.Values.ToList();
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Hero : MonoBehaviour
{
    private HeroInfo info; //hero의 가변적 데이터
    private GameObject model; // hero의 프리팹
    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;

public class HeroData
{
    public int id;
    public string name;
    public float max_hp;
    public float damage;
    public string prefab_name;
    public string sprite_name;
}

 

**hero_data를 수정할 때 , hero_data의 위치 및 문법이 맞는지 꼭 확인하자.

+ Recent posts