멈추지 않고 끈질기게
[Unity][기타] 데이터 경로 관련 본문
※ 해당 포스팅은 개인의 공부 정리용 글입니다. 틀린 내용이 있다면 추후 수정될 수 있습니다.
※ 해당 포스팅은 하기 출처들을 참조하였습니다.
- https://docs.unity3d.com/ScriptReference/Application-dataPath.html
- https://docs.unity3d.com/ScriptReference/Application-persistentDataPath.html
0. 서문
작업하던 포트폴리오 프로젝트에서 유저 데이터를 Resources 폴더가 아닌 다른 경로에 저장하고, Application.dataPath를 사용하여 접근해왔는데 안드로이드 빌드 후 실행해보니 데이터를 읽어오지 못하는 이슈가 발생했습니다. 찾아보니 데이터 경로에도 여러 종류가 있고, 플랫폼에 상관없이 빌드 상에서 읽기/쓰기 작업을 수행하려면 다른 경로를 사용해야 한다는 것을 알게 되었습니다.
1. Application.dataPath
Resources.Load()와 같이 자동으로 Assets/Resources 폴더를 타겟으로 하는 함수의 경우 경로 지정이 쉽지만, 그 외의 방법으로 파일 읽기/쓰기를 실행할 경우 파일 경로를 정확하게 지정해주어야 합니다. Application 클래스에는 이를 위한 static 문자열 변수를 제공하는데, 그 중 하나가 dataPath입니다.
Application.dataPath는 에디터 기준 "(프로젝트 폴더 경로)/Assets"를 반환합니다. 참고로 끝에 /가 없으므로, 경로를 덧붙이려면 /로 시작하여야 합니다(ex. Application.dataPath + "/Json/(파일명)"). 다음은 dataPath를 통해 Asset폴더 내 json 파일을 읽어들이는 코드 예시입니다.
// 데이터 저장용 클래스 선언
[Serializable]
public class StageData
{
public int Hp;
public int EnemyCount;
public int MinEnemyId;
public int MaxEnemyId;
public int DropGold;
public int DropGem;
}
[Serializable]
public class StageDataLoader
{
public List<StageData> StageDatas;
}
public class JsonTest : MonoBehaviour
{
void Start()
{
// 경로 지정
string dataPath = Application.dataPath + "/Json/StageDatas.json";
Debug.Log(dataPath);
StageDataLoader loader = ReadJson(dataPath);
foreach (StageData data in loader.StageDatas)
Debug.Log(data.Hp);
}
StageDataLoader ReadJson(string path)
{
string jsonData = File.ReadAllText(path);
return JsonUtility.FromJson<StageDataLoader>(jsonData);
}
}
Application.dataPath에 Assets 폴더 하위 경로 "/Json/StageDatas.json"을 추가하여 File.ReadAllText()의 경로로 사용하였습니다. 로그 첫번째 줄을 보면 dataPath의 상세 경로를 확인할 수 있습니다(물론 프로젝트 폴더에 따라 달라집니다). 밑으로는 읽어들이기에 성공하여 각 StageData의 Hp 변수를 출력하는 모습입니다.
dataPath는 프로젝트 창에서 쉽게 찾을 수 있는 경로라 에디터 상에서 사용하기에 편리하지만, 문제는 PC외의 플랫폼으로 빌드를 뽑아서 실행할 경우 해당 경로에서 파일을 찾을 수 없는 문제가 있습니다. 따라서 빌드에서 파일의 읽기/쓰기를 실행하려면 다른 경로를 사용해야 합니다.
2. Application.persistentDataPath
Application.persistentDataPath는 각 운영 체제에서 허용하는 읽기/쓰기 가능한 폴더의 경로입니다. dataPath와 마찬가지로 하위 경로를 추가하려면 /로 시작해야 합니다(ex. Application.persistentDataPath + "/Json/StageDatas.json";). 읽기/쓰기 로직을 persistentDataPath를 사용하여 작성하면 빌드에서도 정상적으로 실행할 수 있습니다. 사실 읽기 작업은 데이터를 Resources 폴더에 넣어두고 Resources.Load()를 사용해도 되지만, 쓰기 작업의 경우 경로를 직접 지정해주어야 하므로 persistentDataPath를 사용해야 합니다.
const string GameDatapath = "/GameData.json";
public void SaveGameData()
{
if (CurGameData == null)
return;
string jsonString = JsonUtility.ToJson(CurGameData);
// persistentDataPath를 사용하여 경로 지정
FileStream fileStream = new FileStream(Application.persistentDataPath + GameDataPath, FileMode.Create);
byte[] data = Encoding.UTF8.GetBytes(jsonString);
fileStream.Write(data, 0, data.Length);
fileStream.Close();
}
상기 코드는 포트폴리오 프로젝트에서 유저 데이터를 저장하는 함수를 수정한 것으로, persistentDataPath를 사용하는 방식으로 바꾼 이후 안드로이드 빌드에서 정상적으로 쓰기 작업이 실행됨을 확인할 수 있었습니다.
이 외에도 Application 클래스에는 consoleLogPath, temporaryCachePath와 같은 경로 전달용 문자열 변수가 있었으나, 해당 변수들은 아직 사용해 본 일이 없어서 생략했습니다. 일단 존재를 기억해두고, 추후 사용해보고 정리할만큼의 내용이 나오면 추가하도록 하겠습니다.
'Unity' 카테고리의 다른 글
[Unity] 롤링 배너 구현 (1) | 2023.10.24 |
---|---|
[Unity][Android] Google AdMob 관련 이슈(can only be called from the main thread) (0) | 2023.10.03 |
[Unity] 클릭/터치 인터페이스(IPointerClickHandler, IPointerDownHandler, IPointerUpHandler) (1) | 2023.09.06 |
[Unity] Addressable 기능 (0) | 2023.07.27 |
[Unity][포트폴리오] Rigidbody.AddForce()가 제대로 동작하지 않는 이슈 (0) | 2023.07.03 |