아래 내용들은 <오늘코딩> 유투버를 통해 정리함.

-내용물 + 조립설명서를 통해 건담을 조립한다.
using UnityEngine;
class Data //⭐
{
}
public class TestItem : MonoBehaviour
{
// Start is called once before the first execution of Update after the MonoBehaviour is created
void Start()
{
}
// Update is called once per frame
void Update()
{
}
}
using UnityEngine;
class Data
{
public string nickname; //⭐
public int level; //⭐
public int coin; //⭐
public bool isSkill; //⭐
//기타 등등
}
public class TestItem : MonoBehaviour
{
// Start is called once before the first execution of Update after the MonoBehaviour is created
void Start()
{
}
// Update is called once per frame
void Update()
{
}
}
using UnityEngine;
class Data
{
public string nickname;
public int level;
public int coin;
public bool isSkill;
//기타 등등
}
public class TestItem : MonoBehaviour
{
Data player = new Data() //⭐
{
nickname = "김진", //⭐
level = 50, //⭐
coin = 200, //⭐
isSkill = false //⭐
};
private void Start()
{
}
// Update is called once per frame
void Update()
{
}
}
using UnityEngine;
class Data
{
public string nickname;
public int level;
public int coin;
public bool isSkill;
//기타 등등
}
public class TestItem : MonoBehaviour
{
Data player = new Data()
{
nickname = "김진",
level = 50,
coin = 200,
isSkill = false
};
private void Start()
{
string jsonData = JsonUtility.ToJson(player); //⭐
Debug.Log(jsonData); //⭐
}
}

using UnityEngine;
class Data
{
public string nickname;
public int level;
public int coin;
public bool isSkill;
//기타 등등
}
public class TestItem : MonoBehaviour
{
Data player = new Data()
{
nickname = "김진",
level = 50,
coin = 200,
isSkill = false
};
private void Start()
{
// 1. 건담 조립도(클래스)을 보고 나서 택배 상자로 포장 -> Json으로 변환하는 과정.
string jsonData = JsonUtility.ToJson(player);
// 2. 택배 상자에 건담 조립도(클래스)가 Data 클래스이므로 조립도를 보고 클래스로 변환
Data player2 = JsonUtility.FromJson<Data>(jsonData); //⭐ FromJson<데이터가 들어있는 클래스(조립도) 적으면 됨> ,
Data 클래스로 변환 할 것이기 때문에 반환 타입이 Data이므로 Data 객체 선언
Debug.Log(player2.nickname); //⭐
Debug.Log(player2.level); //⭐
Debug.Log(player2.coin); //⭐
Debug.Log(player2.isSkill); //⭐
}
}

- Scene을 2개 만들 것이다. 슬롯을 클릭하여 게임씬으로 넘어 갈 수 있게. 난 Select 씬이 아닌 MainMenu 씬으로 할 것임.
- Script는 3개 만들 것이다. 각 씬에서 담당하는 Select, Game 데이터를 관리할 DataManager 스크립트를 만들 것




using UnityEngine;
public class DataManager : MonoBehaviour
{
//게임 내에 항상 존재하면 좋으므로 싱글톤
private static DataManager instance;
public static DataManager Instance
{
get
{
if (instance == null)
{
GameObject go = new GameObject("DataManager"); //EventBus라는 빈 객체를 만들고
instance = go.AddComponent<DataManager>(); //EventBus 빈 객체에 EventBus 스크립트(컴포넌트)을 추가
}
return instance;
}
}
private void Awake()
{
if(instance == null)
{
instance = this;
}
else
{
Destroy(instance.gameObject);
}
DontDestroyOnLoad(go);
}
}

using UnityEngine;
public class PlayerData //⭐
{
//이름, 레벨 , 코인, 착용중인 무기 들을 저장
public string name; /⭐
public int level; /⭐
public int coin; /⭐
public int item; /⭐ int로 한 이유는 이 값이 1번이라면 1번에 대응되는 무기. 2번이라면 2번에 대응되는 무기.
}
public class DataManager : MonoBehaviour
{
//게임 내에 항상 존재하면 좋으므로 싱글톤
private static DataManager instance;
public static DataManager Instance
{
get
{
if (instance == null)
{
GameObject go = new GameObject("DataManager"); //EventBus라는 빈 객체를 만들고
instance = go.AddComponent<DataManager>(); //EventBus 빈 객체에 EventBus 스크립트(컴포넌트)을 추가
}
return instance;
}
}
PlayerData nowPlayer = new PlayerData();
private void Awake()
{
#region 싱글톤
if (instance == null)
{
instance = this;
}
else
{
Destroy(instance.gameObject);
}
DontDestroyOnLoad(this.gameObject);
#endregion
}
private void Start()
{
string data = JsonUtility.ToJson(nowPlayer);
}
}
using UnityEngine;
public class PlayerData
{
//이름, 레벨 , 코인, 착용중인 무기 들을 저장
public string name;
public int level;
public int coin;
public int item; //int로 한 이유는 이 값이 1번이라면 1번에 대응되는 무기. 2번이라면 2번에 대응되는 무기.
}
public class DataManager : MonoBehaviour
{
//게임 내에 항상 존재하면 좋으므로 싱글톤
private static DataManager instance;
public static DataManager Instance
{
get
{
if (instance == null)
{
GameObject go = new GameObject("DataManager"); //EventBus라는 빈 객체를 만들고
instance = go.AddComponent<DataManager>(); //EventBus 빈 객체에 EventBus 스크립트(컴포넌트)을 추가
}
return instance;
}
}
PlayerData nowPlayer = new PlayerData(); //⭐
private void Awake()
{
#region 싱글톤
if (instance == null)
{
instance = this;
}
else
{
Destroy(instance.gameObject);
}
DontDestroyOnLoad(this.gameObject);
#endregion
}
private void Start()
{
string data = JsonUtility.ToJson(nowPlayer); //⭐
}
}

using UnityEngine;
using System.IO;
public class PlayerData
{
//이름, 레벨 , 코인, 착용중인 무기 들을 저장
public string name;
public int level;
public int coin;
public int item; //int로 한 이유는 이 값이 1번이라면 1번에 대응되는 무기. 2번이라면 2번에 대응되는 무기.
}
public class DataManager : MonoBehaviour
{
//게임 내에 항상 존재하면 좋으므로 싱글톤
private static DataManager instance;
public static DataManager Instance
{
get
{
if (instance == null)
{
GameObject go = new GameObject("DataManager"); //EventBus라는 빈 객체를 만들고
instance = go.AddComponent<DataManager>(); //EventBus 빈 객체에 EventBus 스크립트(컴포넌트)을 추가
}
return instance;
}
}
PlayerData nowPlayer = new PlayerData();
string path; //⭐
private void Awake()
{
#region 싱글톤
if (instance == null)
{
instance = this;
}
else
{
Destroy(instance.gameObject);
}
DontDestroyOnLoad(this.gameObject);
#endregion
path = Application.persistentDataPath; //⭐
}
private void Start()
{
string data = JsonUtility.ToJson(nowPlayer); //⭐
Debug.Log(path); //⭐
// File.WriteAllText(path,data); //WriteAllText.(경로,어떤걸 저장할지);
}
}


using UnityEngine;
using System.IO; //⭐ 저장하기 위해 File.WriteAllText() 사용해야 함.
public class PlayerData
{
//이름, 레벨 , 코인, 착용중인 무기 들을 저장
public string name;
public int level;
public int coin;
public int item; //int로 한 이유는 이 값이 1번이라면 1번에 대응되는 무기. 2번이라면 2번에 대응되는 무기.
}
public class DataManager : MonoBehaviour
{
//게임 내에 항상 존재하면 좋으므로 싱글톤
private static DataManager instance;
public static DataManager Instance
{
get
{
if (instance == null)
{
GameObject go = new GameObject("DataManager"); //EventBus라는 빈 객체를 만들고
instance = go.AddComponent<DataManager>(); //EventBus 빈 객체에 EventBus 스크립트(컴포넌트)을 추가
}
return instance;
}
}
PlayerData nowPlayer = new PlayerData();
string path;
string filename = "Save"; //⭐ 파일 명까지 정해주는게 나중에 파일 관리할 때 편함. 파일명은 Save
private void Awake()
{
#region 싱글톤
if (instance == null)
{
instance = this;
}
else
{
Destroy(instance.gameObject);
}
DontDestroyOnLoad(this.gameObject);
#endregion
path = Application.persistentDataPath + "/"; //⭐"/" 를 경로 맨 뒤에 붙여줘야 오류가 없음.
}
private void Start()
{
string data = JsonUtility.ToJson(nowPlayer);
File.WriteAllText(path + filename, data); //⭐ WriteAllText.(경로,어떤걸 저장할지);
}
}

using UnityEngine;
using System.IO;
public class PlayerData
{
//이름, 레벨 , 코인, 착용중인 무기 들을 저장
public string name;
public int level;
public int coin;
public int item; //int로 한 이유는 이 값이 1번이라면 1번에 대응되는 무기. 2번이라면 2번에 대응되는 무기.
}
public class DataManager : MonoBehaviour
{
//게임 내에 항상 존재하면 좋으므로 싱글톤
private static DataManager instance;
public static DataManager Instance
{
get
{
if (instance == null)
{
GameObject go = new GameObject("DataManager"); //EventBus라는 빈 객체를 만들고
instance = go.AddComponent<DataManager>(); //EventBus 빈 객체에 EventBus 스크립트(컴포넌트)을 추가
}
return instance;
}
}
PlayerData nowPlayer = new PlayerData();
string path;
string filename = "Save"; //파일 명까지 정해주는게 나중에 파일 관리할 때 편함.
private void Awake()
{
#region 싱글톤
if (instance == null)
{
instance = this;
}
else
{
Destroy(instance.gameObject);
}
DontDestroyOnLoad(this.gameObject);
#endregion
path = Application.persistentDataPath + "/";
}
private void Start()
{
}
public void SaveData() //⭐
{
string data = JsonUtility.ToJson(nowPlayer); //⭐
//저장하기 - WriteAllText() 사용
File.WriteAllText(path + filename, data); //⭐ WriteAllText.(경로,어떤걸 저장할지);
}
}
using UnityEngine;
using System.IO;
public class PlayerData
{
//이름, 레벨 , 코인, 착용중인 무기 들을 저장
public string name;
public int level;
public int coin;
public int item; //int로 한 이유는 이 값이 1번이라면 1번에 대응되는 무기. 2번이라면 2번에 대응되는 무기.
}
public class DataManager : MonoBehaviour
{
//게임 내에 항상 존재하면 좋으므로 싱글톤
private static DataManager instance;
public static DataManager Instance
{
get
{
if (instance == null)
{
GameObject go = new GameObject("DataManager"); //EventBus라는 빈 객체를 만들고
instance = go.AddComponent<DataManager>(); //EventBus 빈 객체에 EventBus 스크립트(컴포넌트)을 추가
}
return instance;
}
}
PlayerData nowPlayer = new PlayerData();
string path;
string filename = "Save"; //파일 명까지 정해주는게 나중에 파일 관리할 때 편함.
private void Awake()
{
#region 싱글톤
if (instance == null)
{
instance = this;
}
else
{
Destroy(instance.gameObject);
}
DontDestroyOnLoad(this.gameObject);
#endregion
path = Application.persistentDataPath + "/";
}
private void Start()
{
}
public void SaveData()
{
string data = JsonUtility.ToJson(nowPlayer);
//저장하기 - WriteAllText() 사용
File.WriteAllText(path + filename, data); //WriteAllText.(경로,어떤걸 저장할지);
}
public void LoadData() //⭐
{
//불러오기 - ReadAllText() 사용
string data = File.ReadAllText(path + filename); //⭐
}
}
using UnityEngine;
using System.IO;
public class PlayerData
{
//이름, 레벨 , 코인, 착용중인 무기 들을 저장
public string name;
public int level;
public int coin;
public int item; //int로 한 이유는 이 값이 1번이라면 1번에 대응되는 무기. 2번이라면 2번에 대응되는 무기.
}
public class DataManager : MonoBehaviour
{
//게임 내에 항상 존재하면 좋으므로 싱글톤
private static DataManager instance;
public static DataManager Instance
{
get
{
if (instance == null)
{
GameObject go = new GameObject("DataManager"); //EventBus라는 빈 객체를 만들고
instance = go.AddComponent<DataManager>(); //EventBus 빈 객체에 EventBus 스크립트(컴포넌트)을 추가
}
return instance;
}
}
PlayerData nowPlayer = new PlayerData();
string path;
string filename = "Save"; //파일 명까지 정해주는게 나중에 파일 관리할 때 편함.
private void Awake()
{
#region 싱글톤
if (instance == null)
{
instance = this;
}
else
{
Destroy(instance.gameObject);
}
DontDestroyOnLoad(this.gameObject);
#endregion
path = Application.persistentDataPath + "/";
}
private void Start()
{
}
public void SaveData()
{
string data = JsonUtility.ToJson(nowPlayer);
//저장하기 - WriteAllText() 사용
File.WriteAllText(path + filename, data); //WriteAllText.(경로,어떤걸 저장할지);
}
public void LoadData()
{
//불러오기 - ReadAllText() 사용
string data = File.ReadAllText(path + filename);
nowPlayer = JsonUtility.FromJson<PlayerData>(data); //⭐ 기존에 선언했던 nowPlayer을 불러오고 나서 덮어 씌우게 됨
}
}







using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;
public class SceneSelect : MonoBehaviour
{
public GameObject creat; //비어있는 슬롯을 눌렀을 때 뜨는 창 (플레이어 이름 적는 UI)
public TextMeshProUGUI[] slotText; //슬롯의 텍스트
public void Slot()
{
//1.저장된 데이터가 없을 때
Creat(); //(플레이어 이름 적는 UI) 활성화 하는 메서드
//2. 저장된 데이터가 있을 때 => 불러오기 해서 게임 씬으로 넘어가게.
DataManager.Instance.LoadData(); //불러오기
GoGame(); //게임 씬으로 넘어가게.
}
public void Creat()
{
creat.gameObject.SetActive(true); //(플레이어 이름 적는 UI) 활성화
}
public void GoGame()
{
SceneManager.LoadScene(1); //인 게임씬
}
}
using UnityEngine;
using System.IO;
public class PlayerData
{
//이름, 레벨 , 코인, 착용중인 무기 들을 저장
public string name;
public int level;
public int coin;
public int item; //int로 한 이유는 이 값이 1번이라면 1번에 대응되는 무기. 2번이라면 2번에 대응되는 무기.
}
public class DataManager : MonoBehaviour
{
//게임 내에 항상 존재하면 좋으므로 싱글톤
private static DataManager instance;
public static DataManager Instance
{
get
{
if (instance == null)
{
GameObject go = new GameObject("DataManager"); //EventBus라는 빈 객체를 만들고
instance = go.AddComponent<DataManager>(); //EventBus 빈 객체에 EventBus 스크립트(컴포넌트)을 추가
}
return instance;
}
}
public PlayerData nowPlayer = new PlayerData();
string path;
string filename = "Save"; //파일 명까지 정해주는게 나중에 파일 관리할 때 편함.
public int nowSlot; //⭐
private void Awake()
{
#region 싱글톤
if (instance == null)
{
instance = this;
}
else
{
Destroy(instance.gameObject);
}
DontDestroyOnLoad(this.gameObject);
#endregion
path = Application.persistentDataPath + "/";
}
private void Start()
{
}
public void SaveData()
{
string data = JsonUtility.ToJson(nowPlayer);
//저장하기 - WriteAllText() 사용
File.WriteAllText(path + filename + nowSlot.ToString(), data); //⭐경로의 파일이름을 지정한 후 데이터를 저장하고 파일 이름 뒤에 슬롯의 번호까지 추가. Save0,Save1...
}
public void LoadData()
{
//불러오기 - ReadAllText() 사용
string data = File.ReadAllText(path + filename + nowSlot.ToString()); //⭐ 경로의 파일이름을 지정한 후 데이터를 저장하고 파일 이름 뒤에 슬롯의 번호까지 추가. Save0,Save1...
nowPlayer = JsonUtility.FromJson<PlayerData>(data); //기존에 선언했던 nowPlayer을 불러오고 나서 덮어 씌우게 됨
}
}
using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;
public class SceneSelect : MonoBehaviour
{
public GameObject creat; //비어있는 슬롯을 눌렀을 때 뜨는 창
public TextMeshProUGUI[] slotText; //슬롯의 텍스트
public void Slot(int number) //⭐ 버튼 클릭 이벤트 호출, int number을 매개변수로
{
DataManager.Instance.nowSlot = number; //⭐ 호출했을 때 매개변수로 받은 숫자가 슬롯의 번호가 되는 개념.
//1.저장된 데이터가 없을 때
Creat();
//2. 저장된 데이터가 있을 때 => 불러오기 해서 게임 씬으로 넘어가게.
DataManager.Instance.LoadData(); //불러오기
GoGame(); //게임 씬으로 넘어가게.
}
public void Creat()
{
creat.gameObject.SetActive(true);
}
public void GoGame()
{
SceneManager.LoadScene(1);//인 게임씬
}
}


게임 씬으로 넘어가는 확인 버튼에 OnClick 이벤트 추가

슬롯 버튼의 OnClick 이벤트에서 Slot메서드로 지정하면 숫자를 입력하는 것이 뜬다.(Slot 메서드에 매개변수로 int타입이므로) 할당 해보자.
0으로 설정

1로 설정

2로 설정


using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;
public class SceneSelect : MonoBehaviour
{
public GameObject creat; //비어있는 슬롯을 눌렀을 때 뜨는 창
public TextMeshProUGUI[] slotText; //슬롯의 텍스트
public TextMeshProUGUI newPlayerName; //⭐ 플레이어 이름 적는 ui - 인풋 필드 텍스트
private void Start()
{
//슬롯별로 저장된 데이터가 존재하는지 판단.
}
public void Slot(int number) //버튼 클릭 이벤트 호출
{
DataManager.Instance.nowSlot = number; //호출했을 때 매개변수로 받은 숫자가 슬롯의 번호가 되는 개념.
//1.저장된 데이터가 없을 때
Creat();
//2. 저장된 데이터가 있을 때 => 불러오기 해서 게임 씬으로 넘어가게.
DataManager.Instance.LoadData(); //불러오기
// ⭐ DataManager.Instance.nowPlayer.name = newPlayerName.text; //⭐ PlayerData 클래스 객체인 name에 새로 적은 플레이어에 이름으로 저장.
GoGame(); //게임 씬으로 넘어가게.
}
public void Creat()
{
creat.gameObject.SetActive(true);
}
public void GoGame() //이름 확인 버튼 누르면 실행
{
//⭐ DataManager.Instance.nowPlayer.name = newPlayerName.text; -> 버그 요소임. 불러오고 나서 이름을 지정하면 빈 문자열이 될 것임.
SceneManager.LoadScene(1);//인 게임씬
}
}

위 추가한 코드를 주석처리 하는 이유는 버그 때문이다. 첫번째 부분을로 주석한 이유는 GoGame메서드가 실행되기 전에 저장하면. 즉, 확인을 누르기도 전에 새로 적은 플레이어 이름을 저장하면 안된다. 그럼 두번째 부분인 확인 버튼을 클릭하고 나서 하면 되지 않나? 했는데 불러오고 나서 이름을 지정하면 빈 문자열이 될 것이다.
using System.IO;
using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;
public class SceneSelect : MonoBehaviour
{
public GameObject creat; //비어있는 슬롯을 눌렀을 때 뜨는 창
public TextMeshProUGUI[] slotText; //슬롯의 텍스트
public TextMeshProUGUI newPlayerName;
bool[] savefile; //⭐ for문에서 파일이 존재하는 지 안하는지 bool 값으로 나옴. bool 배열 사용
private void Start()
{
//⭐ 슬롯별로 저장된 데이터가 존재하는지 판단.
for(int i =0; i <3; i++) //⭐ 슬롯이 현재 3까지 존재 하므로, 0,1,2 범위 사용
{
if (File.Exists(DataManager.Instance.path + i)) //⭐ 즉, Save0~Save2 중에 파일이 존재한다면.ex) Save0 파일 존재
{
savefile[i] = true; //⭐ 해당 Save0~Save2 중 존재한 파일을 true로. ex) Save0 파일을 true로
DataManager.Instance.nowSlot = i; //⭐ 슬롯넘버 할당. ex) Save0 파일의 넘버가 0이므로 0을 슬롯0번으로 할당.
DataManager.Instance.LoadData(); //⭐불러오기
slotText[i].text = DataManager.Instance.nowPlayer.name; //⭐해당 슬롯0번의 텍스트가 PlayerData의 name으로 저장
}
}
}
public void Slot(int number) //버튼 클릭 이벤트 호출
{
DataManager.Instance.nowSlot = number; //호출했을 때 매개변수로 받은 숫자가 슬롯의 번호가 되는 개념.
//1.저장된 데이터가 없을 때
Creat();
//2. 저장된 데이터가 있을 때 => 불러오기 해서 게임 씬으로 넘어가게.
DataManager.Instance.LoadData(); //불러오기
GoGame(); //게임 씬으로 넘어가게.
}
public void Creat()
{
creat.gameObject.SetActive(true);
}
public void GoGame()
{
//DataManager.Instance.nowPlayer.name = newPlayerName.text; -> 버그 요소임. 불러오고 나서 이름을 지정하면 빈 문자열이 될 것임.
SceneManager.LoadScene(1);//인 게임씬
}
}


using UnityEngine;
using System.IO;
public class PlayerData
{
//이름, 레벨 , 코인, 착용중인 무기 들을 저장
public string name;
public int level;
public int coin;
public int item; //int로 한 이유는 이 값이 1번이라면 1번에 대응되는 무기. 2번이라면 2번에 대응되는 무기.
}
public class DataManager : MonoBehaviour
{
//게임 내에 항상 존재하면 좋으므로 싱글톤
private static DataManager instance;
public static DataManager Instance
{
get
{
if (instance == null)
{
GameObject go = new GameObject("DataManager"); //EventBus라는 빈 객체를 만들고
instance = go.AddComponent<DataManager>(); //EventBus 빈 객체에 EventBus 스크립트(컴포넌트)을 추가
}
return instance;
}
}
public PlayerData nowPlayer = new PlayerData();
public string path;
string filename = "Save"; //파일 명까지 정해주는게 나중에 파일 관리할 때 편함.
public int nowSlot;
private void Awake()
{
#region 싱글톤
if (instance == null)
{
instance = this;
}
else
{
Destroy(instance.gameObject);
}
DontDestroyOnLoad(this.gameObject);
#endregion
path = Application.persistentDataPath + "/";
}
private void Start()
{
}
public void SaveData()
{
string data = JsonUtility.ToJson(nowPlayer);
//저장하기 - WriteAllText() 사용
File.WriteAllText(path + filename + nowSlot.ToString(), data); // 경로의 파일이름을 지정한 후 데이터를 저장하고 파일 이름 뒤에 슬롯의 번호까지 추가. Save0,Save1...
}
public void LoadData()
{
//불러오기 - ReadAllText() 사용
string data = File.ReadAllText(path + filename + nowSlot.ToString());
nowPlayer = JsonUtility.FromJson<PlayerData>(data); //기존에 선언했던 nowPlayer을 불러오고 나서 덮어 씌우게 됨
}
public void DataClear() //⭐
{
nowSlot = -1; //⭐슬롯 번호가 -1로 안 갈거니까 -1로 설정.
nowPlayer = new PlayerData(); //⭐초기값으로 다시 초기화
}
}

using System.IO;
using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;
public class SceneSelect : MonoBehaviour
{
public GameObject creat; //비어있는 슬롯을 눌렀을 때 뜨는 창
public TextMeshProUGUI[] slotText; //슬롯의 텍스트
public TextMeshProUGUI newPlayerName;
bool[] savefile = new bool[3]; //⭐ 배열이기 때문에 초기화 해줘야 작동함.
private void Start()
{
//슬롯별로 저장된 데이터가 존재하는지 판단.
for(int i =0; i <3; i++) //슬롯이 현재 3까지 존재 하므로, 0,1,2 범위 사용
{
if (File.Exists(DataManager.Instance.path + i)) //즉, Save0~Save2 중에 파일이 존재한다면.ex) Save0 파일 존재
{
savefile[i] = true; //해당 Save0~Save2 중 존재한 파일을 true로. ex) Save0 파일을 true로
DataManager.Instance.nowSlot = i; //슬롯넘버 할당. ex) Save0 파일의 넘버가 0이므로 0을 슬롯0번으로 할당.
DataManager.Instance.LoadData(); //불러오기
slotText[i].text = DataManager.Instance.nowPlayer.name; //해당 슬롯0번의 텍스트가 PlayerData의 name으로 저장
}
}
DataManager.Instance.DataClear();
}
public void Slot(int number) //버튼 클릭 이벤트 호출
{
DataManager.Instance.nowSlot = number; //호출했을 때 매개변수로 받은 숫자가 슬롯의 번호가 되는 개념.
if (savefile[number]) //⭐ 1. 저장된 데이터가 있다면. 즉, 파일이 존재했다면 -> Start문 참고.
{
DataManager.Instance.LoadData(); //⭐불러오기
GoGame(); //⭐
}
else //⭐ 2.저장된 데이터가 없을 때
{
Creat(); //⭐
}
//⭐ GoGame(); //Creat()가 호출되면 창이 나타나는데 창이 나타나자 마자 바로 게임씬으로 이동하면 안되므로 주석처리
}
public void Creat()
{
creat.gameObject.SetActive(true);
}
public void GoGame()
{
//저장된 데이터가 없을 때 -> 빈 슬롯이였다면
if (savefile[DataManager.Instance.nowSlot] == false) //⭐ Slot 메서드에서 DataManager.Instance.nowSlot을 업데이트 해줬기 때문에 사용 가능.
{
DataManager.Instance.nowPlayer.name = newPlayerName.text; //⭐
DataManager.Instance.SaveData(); //⭐
}
SceneManager.LoadScene(1);//⭐ 인 게임씬
}
}



using UnityEngine;
using System.IO;
public class PlayerData
{
//이름, 레벨 , 코인, 착용중인 무기 들을 저장
public string name;
public int level;
public int coin;
public int item; //int로 한 이유는 이 값이 1번이라면 1번에 대응되는 무기. 2번이라면 2번에 대응되는 무기.
}
public class DataManager : MonoBehaviour
{
//게임 내에 항상 존재하면 좋으므로 싱글톤
private static DataManager instance;
public static DataManager Instance
{
get
{
if (instance == null)
{
GameObject go = new GameObject("DataManager"); //EventBus라는 빈 객체를 만들고
instance = go.AddComponent<DataManager>(); //EventBus 빈 객체에 EventBus 스크립트(컴포넌트)을 추가
}
return instance;
}
}
public PlayerData nowPlayer = new PlayerData();
public string path;
string filename = "Save"; //파일 명까지 정해주는게 나중에 파일 관리할 때 편함.
public int nowSlot;
private void Awake()
{
#region 싱글톤
if (instance == null)
{
instance = this;
}
else
{
Destroy(instance.gameObject);
}
DontDestroyOnLoad(this.gameObject);
#endregion
path = Application.persistentDataPath + "/"; //❗ 프로젝트 경로 + "/"을 해버리면 제대로 찾지 못한다.
}
private void Start()
{
}
public void SaveData()
{
string data = JsonUtility.ToJson(nowPlayer);
//저장하기 - WriteAllText() 사용
File.WriteAllText(path + "Save" + nowSlot.ToString(), data); //❗path + "Save" + nowSlot.ToString() 가 아닌 path + nowSlot.ToString() 로 수정
}
public void LoadData()
{
//불러오기 - ReadAllText() 사용
string data = File.ReadAllText(path + "Save" + nowSlot.ToString()); //❗path + "Save" + nowSlot.ToString() 가 아닌 path + nowSlot.ToString() 로 수정
nowPlayer = JsonUtility.FromJson<PlayerData>(data); //기존에 선언했던 nowPlayer을 불러오고 나서 덮어 씌우게 됨
}
public void DataClear()
{
nowSlot = -1; //슬롯 번호가 -1로 안 갈거니까 -1로 설정.
nowPlayer = new PlayerData(); //초기값으로 다시 초기화
}
}
using UnityEngine;
using System.IO;
public class PlayerData
{
//이름, 레벨 , 코인, 착용중인 무기 들을 저장
public string name;
public int level;
public int coin;
public int item; //int로 한 이유는 이 값이 1번이라면 1번에 대응되는 무기. 2번이라면 2번에 대응되는 무기.
}
public class DataManager : MonoBehaviour
{
//게임 내에 항상 존재하면 좋으므로 싱글톤
private static DataManager instance;
public static DataManager Instance
{
get
{
if (instance == null)
{
GameObject go = new GameObject("DataManager"); //EventBus라는 빈 객체를 만들고
instance = go.AddComponent<DataManager>(); //EventBus 빈 객체에 EventBus 스크립트(컴포넌트)을 추가
}
return instance;
}
}
public PlayerData nowPlayer = new PlayerData();
public string path;
public int nowSlot;
private void Awake()
{
#region 싱글톤
if (instance == null)
{
instance = this;
}
else
{
Destroy(instance.gameObject);
}
DontDestroyOnLoad(this.gameObject);
#endregion
path = Application.persistentDataPath + "/Save"; //👌
}
private void Start()
{
}
public void SaveData()
{
string data = JsonUtility.ToJson(nowPlayer);
//저장하기 - WriteAllText() 사용
File.WriteAllText(path + nowSlot.ToString(), data); //👌 경로의 파일이름을 지정한 후 데이터를 저장하고 파일 이름 뒤에 슬롯의 번호까지 추가. Save0,Save1...
}
public void LoadData()
{
//불러오기 - ReadAllText() 사용
string data = File.ReadAllText(path + nowSlot.ToString()); //👌
nowPlayer = JsonUtility.FromJson<PlayerData>(data); //기존에 선언했던 nowPlayer을 불러오고 나서 덮어 씌우게 됨
}
public void DataClear()
{
nowSlot = -1; //슬롯 번호가 -1로 안 갈거니까 -1로 설정.
nowPlayer = new PlayerData(); //초기값으로 다시 초기화
}
}
실행 결과. 빈 슬롯1,2,3 중에 빈 슬롯 2번에 플레이어 이름을 입력하자. Save1 파일이 생겼고, 파일 안에 내가 적은 플레이어의 이름이 저장되었다. 그리고, 다시 게임 시작한 결과 빈 슬롯 1번에 내가 적은 플레이어의 이름이 적혀있다.

아까 빈 슬롯 1 버튼을 클릭하면 0을 Slot 메서드에 인자로 넘겼었다.









using TMPro;
using UnityEngine;
public class SceneInGame : MonoBehaviour
{
public TextMeshProUGUI name;
public TextMeshProUGUI level;
public TextMeshProUGUI coin;
void Start()
{
//게임 씬에 넘어오면 플레이어의 정보(이름,레벨,코인)이 알맞게 나타나야 함.
name.text += DataManager.Instance.nowPlayer.name; //name 은 현재 이름: 이므로 name += 형태로 진행.
level.text += DataManager.Instance.nowPlayer.level.ToString(); //text string이고 level은 int이므로 ToString()
coin.text += DataManager.Instance.nowPlayer.coin.ToString();
}
public void LevelUp()
{
DataManager.Instance.nowPlayer.level++; //값 바꾸기
level.text = "레벨 : " + DataManager.Instance.nowPlayer.level.ToString(); //UI변화를 위함
}
public void CoinUp()
{
DataManager.Instance.nowPlayer.coin += 100;
coin.text = "코인 : " + DataManager.Instance.nowPlayer.coin.ToString(); //UI변화를 위함
}
public void Save()
{
DataManager.Instance.SaveData();
}
}
레벨하고 코인은 기본 값을 정해주지 않았었다. 기본 값 정해주자.


버튼 이벤트 할당 까지 ㄱㄱ




using TMPro;
using UnityEngine;
public class SceneInGame : MonoBehaviour
{
public TextMeshProUGUI name;
public TextMeshProUGUI level;
public TextMeshProUGUI coin;
public GameObject[] WeaponItem; //⭐
void Start()
{
//게임 씬에 넘어오면 플레이어의 정보(이름,레벨,코인)이 알맞게 나타나야 함.
name.text += DataManager.Instance.nowPlayer.name; //name 은 현재 이름: 이므로 name += 형태로 진행.
level.text += DataManager.Instance.nowPlayer.level.ToString(); //text string이고 level은 int이므로 ToString()
coin.text += DataManager.Instance.nowPlayer.coin.ToString();
}
public void LevelUp()
{
DataManager.Instance.nowPlayer.level++; //값 바꾸기
level.text = "레벨 : " + DataManager.Instance.nowPlayer.level.ToString(); //UI변화를 위함
}
public void CoinUp()
{
DataManager.Instance.nowPlayer.coin += 100;
coin.text = "코인 : " + DataManager.Instance.nowPlayer.coin.ToString(); //UI변화를 위함
}
public void Save()
{
DataManager.Instance.SaveData();
}
public void ItemSetting(int number) //⭐
{
for(int i = 0; i< WeaponItem.Length; i++) //⭐
{
if(number == i) //⭐ 선택한 무기(0)가 첫번째(0) 라면
{
WeaponItem[i].SetActive(true); //⭐첫번째 무기만 활성화
DataManager.Instance.nowPlayer.item = number; //⭐활성화된 무기의 번호가 PlayerData의 item 변수에 저장됨. 즉, 대응 됨.
}
else //⭐ 아니라면
{
WeaponItem[i].SetActive(false); //⭐비활성화
}
}
}
}

소드 버튼은 0번으로 ItemSetting 메서드를 호출할 때 값을 넘긴다.

바주카 버튼은 1번으로 ItemSetting 메서드를 호출할 때 값을 넘긴다.

폭탄 버튼은 2번으로 ItemSetting 메서드를 호출할 때 값을 넘긴다.



