유니티 엔진 클라이언트/수업내용

[유니티] 미션 인포 만들기 (info & data 직, 역직렬화

Bueong_E 2023. 2. 16. 00:30
반응형
SMALL

 

소리 조심 (배경음악이...;;)

코드

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

public class MissionMain : MonoBehaviour
{
    public UIMissionDirector uIMissionDirector;

    private void Start()
    {
        MissionDataManager.instance.LoadData();

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

        if (File.Exists(path))
        {
            Debug.Log("<color=yellow>기존 유저입니다.</color>");
            string json = File.ReadAllText(path);
            var missionInfoList = JsonConvert.DeserializeObject<List<MissionInfo>>(json);

            MissionInfoManager.Instance.missionInfoList = missionInfoList;

            MissionInfoManager.Instance.isNewbie = false;
        }
        else
        {
            var missionListInfo = new MissionInfoManager();
            missionListInfo.Init();

            string json = JsonConvert.SerializeObject(missionListInfo.missionInfoList);
            Debug.LogFormat("<color=red>새로 저장한 인포</color> \n{0} ", json);

            File.WriteAllText(path, json);
            Debug.LogFormat("<color=blue>세이브 완료</color>");

            MissionInfoManager.Instance.missionInfoList = missionListInfo.missionInfoList;

            MissionInfoManager.Instance.isNewbie = true;
        }

        uIMissionDirector.Init();
    }
}
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class UIMissionDirector : MonoBehaviour
{
    public UIMissionScrollView uIMissionScrollView;
    public Button testbutton;


    public void Init()
    {
        this.uIMissionScrollView.Init();
        this.ShowMissionList();

        this.testbutton.onClick.AddListener(() =>
        {
            int ran = UnityEngine.Random.Range(1, 3);
            this.uIMissionScrollView.getInstanceID(ran);
        });
        

    }
    public void ShowMissionList()
    {
        if (MissionInfoManager.Instance.isNewbie)
        {
            this.uIMissionScrollView.CreatMissionList();
        }
        else
        {
            this.uIMissionScrollView.LoadPreviousList();
        }
    }
}
using Microsoft.Unity.VisualStudio.Editor;
using Newtonsoft.Json;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using TMPro;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.U2D;
using UnityEngine.UI;
using static UnityEngine.UI.CanvasScaler;

public class UIMissionScrollView : MonoBehaviour
{
    public GameObject UIMissionCellView;
    public Transform content;
    public Action isClicked;

    public Action<int> getInstanceID;

    int ran;

    public void Init()
    {
        getInstanceID = (x) => {
            this.ran = x;
            this.LoadPreviousList();
        };
    }

    public void CreatMissionList()
    {
        var missionDataList = MissionDataManager.instance.GetMissionDataList();
        var rewardItemDataList = MissionDataManager.instance.GetrewardItemDataList();
        SpriteAtlas atlas = AtlasManager.instance.GetAtlasByName("Mission");

        for (int i = 0; i < missionDataList.Count; i++)
        {
            var cellGo = Instantiate(this.UIMissionCellView, this.content);

            var uIMissionCellViewComp = cellGo.GetComponent<UIMissionCellView>();
            uIMissionCellViewComp.Init(missionDataList[i].id);

            uIMissionCellViewComp.imgIcon.sprite = atlas.GetSprite(missionDataList[i].sprite_name);

            //Debug.Log(missionDataList[i].sprite_name);

            uIMissionCellViewComp.doingIcon.sprite = atlas.GetSprite(rewardItemDataList[i].sprite_name);
            uIMissionCellViewComp.txtName.text = missionDataList[i].name;
            uIMissionCellViewComp.txtGoalDesc.text = string.Format(missionDataList[i].goal_desc, missionDataList[i].goal_value);
            uIMissionCellViewComp.doingText.text = missionDataList[i].reward_item_amount.ToString();
            uIMissionCellViewComp.txtProgress.text = string.Format("0 / {0}", missionDataList[i].goal_value);

            uIMissionCellViewComp.slider.value = 0;

            MissionInfoManager.Instance.AddMissionInfoInList(new MissionInfo(missionDataList[i].id, 0, 0));
            MissionInfoManager.Instance.SaveInventoryInfo();
        }
    }


    public void LoadPreviousList()
    {
        Debug.Log(ran);

        var missionDataList = MissionDataManager.instance.GetMissionDataList();
        var rewardItemDataList = MissionDataManager.instance.GetrewardItemDataList();
        SpriteAtlas atlas = AtlasManager.instance.GetAtlasByName("Mission");
        var list = MissionInfoManager.Instance.missionInfoList;

        this.DeleteChilds();

        for (int i = 0; i < MissionInfoManager.Instance.missionInfoList.Count; i++)
        {
            Debug.LogFormat("미션 인포매니저 카운트 : {0}", MissionInfoManager.Instance.missionInfoList.Count);
            
            var cellGo = Instantiate(this.UIMissionCellView, this.content);           
            var uIMissionCellViewComp = cellGo.GetComponent<UIMissionCellView>();
            uIMissionCellViewComp.Init(list[i].id);

            //Debug.Log(missionDataList[i].sprite_name);

            uIMissionCellViewComp.imgIcon.sprite = atlas.GetSprite(missionDataList[i].sprite_name);
            uIMissionCellViewComp.doingIcon.sprite = atlas.GetSprite(rewardItemDataList[i].sprite_name);
            uIMissionCellViewComp.txtName.text = missionDataList[i].name;
            uIMissionCellViewComp.txtGoalDesc.text = string.Format(missionDataList[i].goal_desc, missionDataList[i].goal_value);
            uIMissionCellViewComp.doingText.text = missionDataList[i].reward_item_amount.ToString();

            uIMissionCellViewComp.update(list[i].status);

            int num = list[i].progress;
            num += ran;

            if (num >= missionDataList[i].goal_value)
            {
                list[i].progress = missionDataList[i].goal_value;
                uIMissionCellViewComp.txtProgress.text = string.Format("{0} / {1}", missionDataList[i].goal_value, missionDataList[i].goal_value);
                uIMissionCellViewComp.slider.value = 1;
                list[i].status = 1;
                uIMissionCellViewComp.update(list[i].status);
            }
            else
            {

                list[i].progress = num;
                uIMissionCellViewComp.txtProgress.text = string.Format("{0} / {1}", list[i].progress, missionDataList[i].goal_value);
                uIMissionCellViewComp.slider.value = list[i].progress / missionDataList[i].goal_value; 
            }
            
            
            GameObject imgRewardItemGO= uIMissionCellViewComp.rewardItemGo.transform.GetChild(0).gameObject;
            imgRewardItemGO.GetComponent<UnityEngine.UI.Image>().sprite = atlas.GetSprite(rewardItemDataList[i].sprite_name);
            GameObject imgRewardItemAmountGO = uIMissionCellViewComp.rewardItemGo.transform.GetChild(1).gameObject;
            imgRewardItemAmountGO.GetComponent<TMP_Text>().text = missionDataList[i].reward_item_amount.ToString();


            //객체 인포 저장                    
            //Debug.LogFormat("{0} 해당 아이디의 미션인포를 가지고 있습니다.", List[i].id);            
            MissionInfoManager.Instance.SaveInventoryInfo();
        }
    }
    public void DeleteChilds()
    {
        var child = this.content.gameObject.GetComponentsInChildren<RectTransform>();

        foreach (var iter in child)
        {
            if (iter != this.content.transform)
            {
                Destroy(iter.gameObject);
            }
        }
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using TMPro;

public class UIMissionCellView : MonoBehaviour
{
    public Image imgIcon;
    public Image doingIcon;

    public TMP_Text txtName;
    public TMP_Text txtGoalDesc;
    public TMP_Text doingText;
    public TMP_Text txtProgress;

    public GameObject btnDoneGo;
    public GameObject btnCompleteGo;
    public GameObject rewardItemGo;


    public Sprite compSprite;
    public Slider slider;

    private int id;
    public int status;

    public void Init(int id)
    {
        this.status = 0;
        this.id = id;
        this.btnDoneGo.gameObject.SetActive(false);   
        this.btnCompleteGo.gameObject.SetActive(false);   
        this.rewardItemGo.gameObject.SetActive(false);
        GameObject btnDoneGo = this.btnDoneGo.transform.GetChild(0).gameObject;
        Button btnCdone = btnDoneGo.GetComponent<Button>();
        btnCdone.onClick.AddListener(() =>
        {
            Debug.Log("버튼클릭");
            this.update(2);
        });
    }

    public void update(int status) 
    {
        if(status == 1) 
        {
            this.ActivateDone();
        }
        else if(status == 2) 
        {
            this.ActivateComplete();
        }
    }
    

    private void ActivateDone()
    {
        this.btnDoneGo.gameObject.SetActive(true);
        this.rewardItemGo.gameObject.SetActive(true);
        this.slider.gameObject.SetActive(false);
        this.status = 1;

    }

    private void ActivateComplete()
    {
        this.btnCompleteGo.gameObject.SetActive(true);
        this.slider.gameObject.SetActive(false);
        this.status = 2;
        this.GetComponent<Image>().sprite = this.compSprite;        

        foreach(var mission in MissionInfoManager.Instance.missionInfoList)
        {
            if(mission.id == this.id)
            {
                mission.status = this.status;
                MissionInfoManager.Instance.SaveInventoryInfo();
                break;
            }
        }


    }


}

구현사항

 

  • info 데이터를 저장하여 미션 진행도를 저장
  • 진행도가 꽉차면 보상 수령버튼 활성화 (영상에서는 약간의 버그로 진행도가 꽉차고 한번더 진행도 증가시 수령버튼이 나왔지만 현재 해결)
  • 수령버튼을 누르면 스프라이트 배경 변경 및 완료 버튼 으로 전환
  • 위 상황 별로 실시간으로 유저 진행 데이터 저장
  • 진행상황과 퀘스트 목표의 비율에 맞춘 진행도 슬라이드  (영상에서는 버그로 진행도 꽉찼을때만 보였지만 현재 수정)

 

 

수정 & 보완점

 

  • 코드가 전체적으로 길어지고 지저분해져서 좀더 메서드를 사용하여 코드를 줄이는 연습을 해야할것 같다. (특히 UIMissionScrollView 스크립트가 많이 지저분해 이부분은 역할을 하위 스크립트로 옮기고 메서드를 좀더 추가하여 사용하기 위한 정리가 필요하다.)
  • 각 스크립트별 역할이 조금 모호한 부분이 있어서 이 부분은 선생님 구조를 참고하여 보완필요
  • 아직 어떤 타이밍에 정확하게 데이터를 저장하고 변경해야하는지 조금 미숙한 부분이 있는데 이부분도 보완필요
  • 보상 스프라이트가 깨져서 나오는데 이 부분은 네이티브 사이즈로 변경하여 수정예정 (안맞으면 사이즈 조절하면 되니까)
  • 오늘은 UI를 프리팹으로 가져와 작업했으니 직접 처음부터 끝까지 만드는 연습필요할듯
반응형
LIST