유니티 - 리스트 삭제 생성 코드 해석하기

Yeons·2022년 12월 3일

스터디

목록 보기
6/8

출처 : https://coding-of-today.tistory.com/181
오늘코딩님의 코드를 해석해보았습니다.


1

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
using System.IO;

public class Select : MonoBehaviour
{
    public GameObject creat;	// 플레이어 닉네임 입력UI
    public Text[] slotText;		// 슬롯버튼 아래에 존재하는 Text들
    public Text newPlayerName;	// 새로 입력된 플레이어의 닉네임

    bool[] savefile = new bool[3];	// 세이브파일 존재유무 저장

    void Start()
    {
        // 슬롯별로 저장된 데이터가 존재하는지 판단.
        for (int i = 0; i < 3; i++)
        {
            if (File.Exists(DataManager.instance.path + $"{i}"))	// 데이터가 있는 경우
            {
                savefile[i] = true;			// 해당 슬롯 번호의 bool배열 true로 변환
                DataManager.instance.nowSlot = i;	// 선택한 슬롯 번호 저장
                DataManager.instance.LoadData();	// 해당 슬롯 데이터 불러옴
                slotText[i].text = DataManager.instance.nowPlayer.name;	// 버튼에 닉네임 표시
            }
            else	// 데이터가 없는 경우
            {
                slotText[i].text = "비어있음";
            }
        }
        // 불러온 데이터를 초기화시킴.(버튼에 닉네임을 표현하기위함이었기 때문)
        DataManager.instance.DataClear();	
    }

    public void Slot(int number)	// 슬롯의 기능 구현
    {
        DataManager.instance.nowSlot = number;	// 슬롯의 번호를 슬롯번호로 입력함.

        if (savefile[number])	// bool 배열에서 현재 슬롯번호가 true라면 = 데이터 존재한다는 뜻
        {
            DataManager.instance.LoadData();	// 데이터를 로드하고
            GoGame();	// 게임씬으로 이동
        }
        else	// bool 배열에서 현재 슬롯번호가 false라면 데이터가 없다는 뜻
        {
            Creat();	// 플레이어 닉네임 입력 UI 활성화
        }
    }

    public void Creat()	// 플레이어 닉네임 입력 UI를 활성화하는 메소드
    {
        creat.gameObject.SetActive(true);
    }

    public void GoGame()	// 게임씬으로 이동
    {
        if (!savefile[DataManager.instance.nowSlot])	// 현재 슬롯번호의 데이터가 없다면
        {
            DataManager.instance.nowPlayer.name = newPlayerName.text; // 입력한 이름을 복사해옴
            DataManager.instance.SaveData(); // 현재 정보를 저장함.
        }
        SceneManager.LoadScene(1); // 게임씬으로 이동
    }
}

creat.gameObject.SetActive(true);

오브젝트를 활성화, 비활성화 시킴

SceneManager.LoadScene(1);

함수에서 씬 이름 대신에 인덱스를 사용하여 해당 씬을 로드할수있으며 SceneManagement 네임스페이스 사용을 선언해야 해당 함수를 사용할수있다.

File.Exists();

문서 내의 데이터가 있을 때

DataManager.instance.LoadData()

데이터값을 읽어옴


2

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

public class PlayerData
{
    // 이름, 레벨, 코인, 착용중인 무기
    public string name;
    public int level = 1;
    public int coin = 100;
    public int item = -1;
}

public class DataManager : MonoBehaviour
{
    public static DataManager instance; // 싱글톤패턴

    public PlayerData nowPlayer = new PlayerData(); // 플레이어 데이터 생성

    public string path; // 경로
    public int nowSlot; // 현재 슬롯번호

    private void Awake()
    {
        #region 싱글톤
        if (instance == null)
        {
            instance = this;
        }
        else if (instance != this)
        {
            Destroy(instance.gameObject);
        }
        DontDestroyOnLoad(this.gameObject);
        #endregion

        path = Application.persistentDataPath + "/save";	// 경로 지정
        print(path);
    }

    public void SaveData()
    {
        string data = JsonUtility.ToJson(nowPlayer);
        File.WriteAllText(path+ nowSlot.ToString(), data);
    }

    public void LoadData()
    {
        string data = File.ReadAllText(path + nowSlot.ToString());
        nowPlayer = JsonUtility.FromJson<PlayerData>(data);
    }

    public void DataClear()
    {
        nowSlot = -1;
        nowPlayer = new PlayerData();
    }
}

Awake & Start 차이점

Awake가 먼저 호출 되고 Start가 호출 된다는 호출 순서와, Awake는 Start와 달리 스크립트가 비활성화 상태일 때도 호출 된다는 차이를 가지고 있다. Start와 Awake를 함께 사용하면 두 단계의 초기화를 차례로 제공할수 있다.

이것은 객체와 컴포넌트 사이에 참조 생성하는 코드를 실제 참조들을 사용하여 동작하는 코드들로 분리할 수 있다는 뜻이다. 이것은 스크립트를 초기화할 때 null 참조 오류를 피하기가 더 쉽게 만들어 준다.이런 작업을 수행할 때 딱히 정해진 규칙은 없지만 어떤 종류의 코드가 Start와 Awake에서 각각 실행 되는지 안다면 도움이 될 수 있다. 예를 들어 한 가지 접근 방식은 Awake를 사용하여 객체 자체 참조 및 변수를 초기화한 다음(예: 개체와 자체 컴포넌트 간의 연결 만들기) Start는 다른 객체나 그것의 컴포넌트에 접근하는 참조를 생성하는데 사용하는 것이다. 이런 접근 방식은 스크립트가 앞에서 살펴본 예제와 같이 아직 초기화 되지 않은 참조를 사용하려고하거나 Awake에서 호출 되면 제대로 작동하지 않는 함수를 사용하는 것을 방지한다(예: Audio Mixer의 값을 조정하기 위해 SetFloat를 호출하는 경우). 이것이 얼마나 유용할지는 전적으로 프로젝트와 구조에 따라 다르지만 일반적으로 오류를 피하기 위해 스크립트를 초기화할 때 Awake와 Start를 모두 사용하는 것이 좋다.

JSON

JSON의 데이터는 키(Key)와 값(Value) 쌍(Pair)로 이루어진 데이터를 저장하는데, items와 같이 배열로 된 데이터 역시 저장이 가능하고 객체 안에 객체를 넣는 것도 가능하며 위의 데이터 내용이 문자열로 이루어져 있기 때문에 사람이 알아보기가 매우 쉽다. JSON 데이터에서 { } 는 객체를 의미하고, [ ] 는 순서가 있는 배열을 나타낸다. 그리고 JSON은 정수, 실수, 문자열, 불리언, null 타입의 데이터 타입을 지원한다.

Application.persistentDataPath + "/save"

파일 경로

JsonUtility 클래스

ObjectToJson() 함수는 JsonUtility 클래스의 ToJson() 함수를 이용해서 오브젝트를 문자열로 된 JSON 데이터로 변환하여 반환하는 처리를 하고 JsonToObject() 함수는 FromJson() 함수를 이용해서 문자열로 된 JSON 데이터를 받아서 원하는 타입의 객체로 반환하는 처리를 한다.

File.WriteAllText

새 파일을 만들고 파일에 내용을 쓴 다음 파일을 닫습니다. 대상 파일이 이미 있으면 덮어씁니다.

File.ReadAllText

텍스트 파일을 열고, 파일의 모든 텍스트를 문자열로 읽어 들인 다음에 파일을 닫습니다.

DontDestroyOnLoad

유니티에서는 새로운 씬을 불러오면 이전 씬에 남아있던 게임 오브젝트들은 모두 사라진다. 하지만 개발자의 의도나 설계에 따라서 몇몇 게임 오브젝트들은 다른 씬으로 넘어갈 때 파괴되지 않도록 할 필요성이 생길 수도 있다. 씬 로드시 파괴하지 않을 오브젝트로 만들려면 바로 위의 코드처럼 DontDestroyOnLoad()함수를 호출해서 매개변수로 자신의 게임 오브젝트를 전달하면 된다.


3

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

public class Game : MonoBehaviour
{
	public Text name;
    public Text level;
    public Text coin;
    
    public GameObject[] item;
    
    void Start()
    {
    	name.text += DataManager.instance.nowPlayer.name;
        level.text += DataManager.instance.nowPlayer.level.ToString();
        coin.text += DataManager.instance.nowPlayer.coin.ToString();
        ItemSetting(DataManager.instance.nowPlayer.item);
    }
    
    public void LevelUp()
    {
    	DataManager.instance.nowPlayer.level++;
        level.text = "레벨 : " + DataManager.instance.nowPlayer.level.ToString();
    }
    
    public void CoinUp()
    {
    	DataManager.instance.nowPlayer.coin++;
    	coin.text = "코인 : " + DataManager.instance.nowPlayer.coin.ToString();
    }
    
    public void Save()
    {
    	DataManager.instance.SaveData();
    }
    
    public void ItemSetting(int number)
    {
    	for(int i = 0; i < item.Length; i++)
        {
        	if(number == i)
            {
            	item[i].SetActive(true);
                DataManager.instance.nowPlayer.item = number;
            }
            else
            {
            	item[i].SetActive(false);
            }
        }
    }

}

ToString()

C#에서 특정 값을 문자열로 변환하기 위해 Convert.ToString() 함수 또는 ToString() 함수를 사용합니다. 두 함수는 null 처리 방식이 다릅니다. Convert.ToString() 함수는 값이 null인 경우 빈 값으로 반환하는데, ToString() 함수는 null을 처리하는 로직이 존재하지 않습니다.

profile
공부중

0개의 댓글