IEnumerator Start ()
{
Debug.Log("파일 생성중");
if (System.IO.File.Exists("Assets/Resources/StatData.csv"))
{
Debug.Log("이미 있음");
//기존에 있던 내용은 내용 수정
//기존에 없던 내용은 내용 추가
// id 활용해서 판단
/*List<StatData> statDatas = new List<StatData>();
var all = GameObject.FindObjectsOfType<Transform>(true);//모든 게임 오브젝트 다
foreach(var go in all)
{
var scripts = go.gameObject.GetComponents<MonoBehaviour>();
foreach(var script in scripts)
{
Type type = script.GetType();
var fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
//bool hasInt = false;
foreach (FieldInfo field in fields)
{
if (field.FieldType == typeof(StatData))
{
//StatData내용 받아오기
}
}
}
}*/
var targets = GameObject.FindObjectsOfType<CharTest>(true);
Dictionary<int, StatData> datas = new Dictionary<int, StatData>();
List<List<string>> modifiedTxt = new List<List<string>>();
bool isChanged = false;
foreach (CharTest t in targets)
{
datas.Add(t.data.id, t.data);
}
using (var csv = new StreamReader("Assets/Resources/StatData.csv"))
{
var txt = csv.ReadToEnd(); //내부 내용 다 읽어오는거 확인함
var txtLine = txt.Split('\n'); // 줄 바꿈 기준으로 나눔
for(int i = 0; i < 2; i++) //수정 버전에 초반부분 등록
{
var line = txtLine[i].Split(',');
line[line.Length - 1] = line[line.Length - 1].Replace("\r", "");
modifiedTxt.Add(line.ToList());
/*for(int j = 0; j < line.Length; j++)
{
modifiedTxt[i][j] = line[j];
}*/
}
for(int i = 2; i < txtLine.Length - 1; i++) // 첫번째건 이름, 두번째건 자료형
{
var id = int.Parse(txtLine[i].Split(',')[0]); // 각 줄을 ,로 나눠서 첫번째 내용 -> id를 int로
if (datas.ContainsKey(id)) // 이미 있었다면
{
isChanged = true;
var data = datas[id];
List<string> line = new List<string>();
//txtLine[i] = $"{data.id},{data.Name},{data.Hp},{data.Exp},{data.Str},{data.Dex},{data.Con},{data.Int}";
line.Add(data.id.ToString());
line.Add(data.Name.ToString());
line.Add(data.Level.ToString());
line.Add(data.Hp.ToString());
line.Add(data.Exp.ToString());
line.Add(data.Str.ToString());
line.Add(data.Dex.ToString());
line.Add(data.Con.ToString());
line.Add(data.Int.ToString());
modifiedTxt.Add(line);
datas.Remove(id);
}
else
{
var line = txtLine[i].Split(',');
line[line.Length - 1] = line[line.Length - 1].Replace("\r", "");
modifiedTxt.Add(line.ToList());
}
}
}
if(datas.Count > 0)
{
isChanged = true;
foreach (var Rdata in datas)
{
List<string> line = new List<string>();
//txtLine[i] = $"{data.id},{data.Name},{data.Hp},{data.Exp},{data.Str},{data.Dex},{data.Con},{data.Int}";
var data = Rdata.Value;
line.Add(data.id.ToString());
line.Add(data.Name.ToString());
line.Add(data.Level.ToString());
line.Add(data.Hp.ToString());
line.Add(data.Exp.ToString());
line.Add(data.Str.ToString());
line.Add(data.Dex.ToString());
line.Add(data.Con.ToString());
line.Add(data.Int.ToString());
modifiedTxt.Add(line);
}
}
if (isChanged)
{
using (var writer = new CsvFileWriter("Assets/Resources/StatData.csv"))
{
//내용 추가하는 공간
foreach (var txt in modifiedTxt)
{
writer.WriteRow(txt);
}
}
}
}
CsvFileWriter의 WriteRow함수는 변수로 List<string>을 요구해서 저런 기형적인 Add난사가 나오게 됐다
현재 씬 내에 CharTest타입을 전부 가져와서
그 안에 있는 StatData에 대해서 현재 csv파일과 대조하고, id가 겹치는 값은 변경됐다고 간주해서 값을 변경시키고,
그 외에는 그냥 그대로 내리거나, 아예 없던값은 추가한다.
위에 주석처리된 내용은 StatData를 변수로 가지고있는 스크립트들을 전부 확인해서 그 안에 StatData를 값으로 받아오려했는데,
확인하는것 까진 되는데 값을 받아오는걸 어떻게 해야할지 모르겠다.


+
수정
IEnumerator Start ()
{
Debug.Log("파일 생성중");
if (System.IO.File.Exists("Assets/Resources/StatData.csv"))
{
Debug.Log("이미 있음");
//기존에 있던 내용은 내용 수정
//기존에 없던 내용은 내용 추가
// id 활용해서 판단
Dictionary<int, StatData> statDatas = new Dictionary<int, StatData>();
var all = GameObject.FindObjectsOfType<Transform>(true);//모든 게임 오브젝트 다
foreach (var go in all)
{
var scripts = go.gameObject.GetComponents<MonoBehaviour>();
foreach (var script in scripts)
{
Type type = script.GetType();
var fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
//bool hasInt = false;
foreach (FieldInfo field in fields)
{
if (field.FieldType == typeof(StatData))
{
//StatData내용 받아오기
StatData data = field.GetValue(script) as StatData;
//Debug.Log(data.id);
statDatas.Add(data.id, data);
}
}
}
}
List<List<string>> modifiedTxt = new List<List<string>>();
bool isChanged = false;
using (var csv = new StreamReader("Assets/Resources/StatData.csv"))
{
var txt = csv.ReadToEnd(); //내부 내용 다 읽어오는거 확인함
var txtLine = txt.Split('\n'); // 줄 바꿈 기준으로 나눔
for(int i = 0; i < 2; i++) //수정 버전에 초반부분 등록
{
var line = txtLine[i].Split(',');
line[line.Length - 1] = line[line.Length - 1].Replace("\r", "");
modifiedTxt.Add(line.ToList());
/*for(int j = 0; j < line.Length; j++)
{
modifiedTxt[i][j] = line[j];
}*/
}
for(int i = 2; i < txtLine.Length - 1; i++) // 첫번째건 이름, 두번째건 자료형
{
var id = int.Parse(txtLine[i].Split(',')[0]); // 각 줄을 ,로 나눠서 첫번째 내용 -> id를 int로
if (statDatas.ContainsKey(id)) // 이미 있었다면
{
isChanged = true;
var data = statDatas[id];
List<string> line = new List<string>();
//txtLine[i] = $"{data.id},{data.Name},{data.Hp},{data.Exp},{data.Str},{data.Dex},{data.Con},{data.Int}";
line.Add(data.id.ToString());
line.Add(data.Name.ToString());
line.Add(data.Level.ToString());
line.Add(data.Hp.ToString());
line.Add(data.Exp.ToString());
line.Add(data.Str.ToString());
line.Add(data.Dex.ToString());
line.Add(data.Con.ToString());
line.Add(data.Int.ToString());
modifiedTxt.Add(line);
statDatas.Remove(id);
}
else
{
var line = txtLine[i].Split(',');
line[line.Length - 1] = line[line.Length - 1].Replace("\r", "");
modifiedTxt.Add(line.ToList());
}
}
}
if(statDatas.Count > 0)
{
isChanged = true;
foreach (var Rdata in statDatas)
{
List<string> line = new List<string>();
//txtLine[i] = $"{data.id},{data.Name},{data.Hp},{data.Exp},{data.Str},{data.Dex},{data.Con},{data.Int}";
var data = Rdata.Value;
line.Add(data.id.ToString());
line.Add(data.Name.ToString());
line.Add(data.Level.ToString());
line.Add(data.Hp.ToString());
line.Add(data.Exp.ToString());
line.Add(data.Str.ToString());
line.Add(data.Dex.ToString());
line.Add(data.Con.ToString());
line.Add(data.Int.ToString());
modifiedTxt.Add(line);
}
}
if (isChanged)
{
using (var writer = new CsvFileWriter("Assets/Resources/StatData.csv"))
{
//내용 추가하는 공간
foreach (var txt in modifiedTxt)
{
writer.WriteRow(txt);
}
}
}
}
GetValue(script) as StatData를 하면 안에 다른 내용이 있더라도 정확히 StatData의 내용만 불러와진다.
그렇게 주석처리 되어있던걸 해결했다.
+
추가
IEnumerator Start ()
{
Debug.Log("파일 생성중");
if (System.IO.File.Exists("Assets/Resources/StatData.csv"))
{
Debug.Log("이미 있음");
//기존에 있던 내용은 내용 수정
//기존에 없던 내용은 내용 추가
// id 활용해서 판단
// 1) StatData 타입 검색 (문자열 기반)
var statDataType = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(a => a.GetTypes())
.FirstOrDefault(t => t.Name == "StatData");
// 2) 타입이 없으면 스킵
if (statDataType == null)
{
Debug.LogWarning("StatData 클래스가 정의되지 않아 처리하지 않습니다.");
yield break;
}
Dictionary<int, dynamic> statDatas = new Dictionary<int, dynamic>();
var all = GameObject.FindObjectsOfType<Transform>(true);//모든 게임 오브젝트 다
foreach (var go in all)
{
var scripts = go.gameObject.GetComponents<MonoBehaviour>();
foreach (var script in scripts)
{
Type type = script.GetType();
var fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
//bool hasInt = false;
foreach (FieldInfo field in fields)
{
if (field.FieldType == statDataType)
{
//StatData내용 받아오기
var data = field.GetValue(script);
var idField = statDataType.GetField("id",
BindingFlags.Instance | BindingFlags.Public);
int idValue = (int)idField.GetValue(data);
//Debug.Log(data.id);
statDatas.Add(idValue, data);
}
}
}
}
List<List<string>> modifiedTxt = new List<List<string>>();
bool isChanged = false;
using (var csv = new StreamReader("Assets/Resources/StatData.csv"))
{
var txt = csv.ReadToEnd(); //내부 내용 다 읽어오는거 확인함
var txtLine = txt.Split('\n'); // 줄 바꿈 기준으로 나눔
for(int i = 0; i < 2; i++) //수정 버전에 초반부분 등록
{
var line = txtLine[i].Split(',');
line[line.Length - 1] = line[line.Length - 1].Replace("\r", "");
modifiedTxt.Add(line.ToList());
/*for(int j = 0; j < line.Length; j++)
{
modifiedTxt[i][j] = line[j];
}*/
}
for(int i = 2; i < txtLine.Length - 1; i++) // 첫번째건 이름, 두번째건 자료형
{
var id = int.Parse(txtLine[i].Split(',')[0]); // 각 줄을 ,로 나눠서 첫번째 내용 -> id를 int로
if (statDatas.ContainsKey(id)) // 이미 있었다면
{
isChanged = true;
var data = statDatas[id];
List<string> line = new List<string>();
//txtLine[i] = $"{data.id},{data.Name},{data.Hp},{data.Exp},{data.Str},{data.Dex},{data.Con},{data.Int}";
line.Add(data.id.ToString());
line.Add(data.Name.ToString());
line.Add(data.Level.ToString());
line.Add(data.Hp.ToString());
line.Add(data.Exp.ToString());
line.Add(data.Str.ToString());
line.Add(data.Dex.ToString());
line.Add(data.Con.ToString());
line.Add(data.Int.ToString());
modifiedTxt.Add(line);
statDatas.Remove(id);
}
else
{
var line = txtLine[i].Split(',');
line[line.Length - 1] = line[line.Length - 1].Replace("\r", "");
modifiedTxt.Add(line.ToList());
}
}
}
if(statDatas.Count > 0)
{
isChanged = true;
foreach (var Rdata in statDatas)
{
List<string> line = new List<string>();
//txtLine[i] = $"{data.id},{data.Name},{data.Hp},{data.Exp},{data.Str},{data.Dex},{data.Con},{data.Int}";
var data = Rdata.Value;
line.Add(data.id.ToString());
line.Add(data.Name.ToString());
line.Add(data.Level.ToString());
line.Add(data.Hp.ToString());
line.Add(data.Exp.ToString());
line.Add(data.Str.ToString());
line.Add(data.Dex.ToString());
line.Add(data.Con.ToString());
line.Add(data.Int.ToString());
modifiedTxt.Add(line);
}
}
if (isChanged)
{
using (var writer = new CsvFileWriter("Assets/Resources/StatData.csv"))
{
//내용 추가하는 공간
foreach (var txt in modifiedTxt)
{
writer.WriteRow(txt);
}
}
}
}
StatData로 선언되어있던 내용을
Dynamic과 Reflection을 이용하여 해결했다
Reflection에 대해 아는 내용이 많이 없어 자세하겐 모르겠다.
1.
var statDataType = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(a => a.GetTypes())
.FirstOrDefault(t => t.Name == "StatData");
SelectMany는 배열 형태라면 쓸 수 있는 함수이다. 매개변수로는 Func를 받는다
이후 내일 정리
해당 내용은 그냥 유니티 기본 세팅으로 안되고


project Setting -> Player에서 api수준을 바꿔놔야한다