프로그래밍/유니티 개발

유니티에서 CSV 파일, 구글 공유 스프레드시트 읽기

백사니 2025. 4. 12. 16:19
728x90
반응형

데이터를 저장하고 읽어올 때 유니티 내의 ScriptableObject를 이용해 관리를 한다.

ScriptableObject는 자료형(int, float, string, 등등)을 자유롭게 저장이 가능하며 코드와 동기화되고 사용하기 편하다. 

 

하지만 scriptableObject 정보를 수정하려면 Unity 에디터가 필요하기 때문에 관리 측면에서 불편하다.

또한 빌드파일에 포함되기에 빌드 후 수정하면 재빌드 해야한다는 단점이 있다. 이러한 단점은 급하게 값을 바꿔야할 때 패치를 해야한다는 번거로움이 생길 수 있다.

 

때문에 이러한 정보를 CSV( Comma-Separated Values ) 파일에 저장해 유니티에서 필요할때 읽고 이를 파싱해 주로 사용한다.

CSV파일은 엑셀로도 편하게 작성하고 변환할 수 있는데 변환한 CSV파일을 유니티 프로젝트 내에 저장해 읽어올 수 있다.

위 과정으로 csv파일을 다운로드 받을 수 있다.

 

이후 

public class PassiveCSVReader : MonoBehaviour
{
	void Start()
    {
    	// csv파일의 경로
        string path = Path.Combine(Application.streamingAssetsPath, "파일명.csv");
        // ReadCSV함수로 데이터 리스트 받기
        List<string[]> csvData = ReadCSV(path);
			
        // 데이터 로그로 확인하기
        foreach (var row in csvData)
        {
            Debug.Log(string.Join(" | ", row));
        }
    }

	// CSV 파일을 읽는 함수
    List<string[]> ReadCSV(string filePath)
    {
    	// 결과를 저장할 리스트
        List<string[]> result = new List<string[]>();

		// 해당 위치에 파일이 존재하는지
        if (File.Exists(filePath))
        {
        	// 해당 파일 줄 단위로 저장
            string[] lines = File.ReadAllLines(filePath);

			// 각 줄을 한줄씩
            foreach (string line in lines)
            {
            	// 각 줄을 ,를 기준으로 fields에 저장
                string[] fields = line.Split(',');
                // 결과 리스트에 추가
                result.Add(fields);
            }
        }
        // 존재하지 않는다면
        else
        {
            Debug.LogError("CSV 파일을 찾을 수 없습니다: " + filePath);
        }

        return result;
    }
}

위와 같이 필요에 따라 파싱한다.

 

그렇다면 csv파일을 수정하는 것이 아니라 공유 파일을 읽어오는 것은 불가능할까?

만약 가능하다면 실시간으로 값을 수정하고 이것이 반영되지 않을까?

 

유니티에서는 이를 지원해준다.

구글 스프레드시트의 링크를 통해서 csv 파일을 읽을 수 있다.

public class PassiveCSVReader : MonoBehaviour
{
    private string _truckCsvUrl = "스프레드시트 주소";

    [SerializeField] private PassiveStatUpgradeValue _scriptable;
    void Start()
    {
        StartCoroutine(DownloadCSV());
    }

    IEnumerator DownloadCSV()
    {
        UnityWebRequest www = UnityWebRequest.Get(_truckCsvUrl);
        yield return www.SendWebRequest();

        if (www.result != UnityWebRequest.Result.Success)
        {
            Debug.LogError("CSV 다운로드 실패: " + www.error);
        }
        else
        {
            string csvText = www.downloadHandler.text;
            ParseCSV(csvText);
        }
    }

    void ParseCSV(string csv)
    {
        string[] lines = csv.Split('\n');
        string[] golds = new string[lines[0].Length];
        string[] stats = new string[lines[0].Length];

        foreach (var line in lines)
        {
            string[] fields = line.Split(',');
            Debug.Log(string.Join(" | ", fields));
            if (fields[0] == "STAT")
            {
                for(int i = 1; i < fields.Length; i++)
                {
                    _scriptable.TrunkValue[i - 1].State = int.Parse(fields[i]);
                }
            }
            else if (fields[0] == "GOLD")
            {
                for (int i = 1; i < fields.Length; i++)
                {
                    _scriptable.TrunkValue[i - 1].Gold = int.Parse(fields[i]);
                }
            }
        }
        
    }
}

아래 코드는 구글 시프레드시트를 읽어서 유니티의 ScriptableObject에 저장시켜주는 코드이다.

UnityWebRequest를 통해서 데이터를 요청해 받아오며, 해당 과정은 서버에 데이터를 요청하는 과정이기에 즉각적으로 반응이 오지 않는다. 때문에 코루틴을 이용해 비동기로 처리한다.

 

구글 스프레드시트를 연동시키려면

파일 -> 공유 -> 다른 사용자와 공유 -> 링크가 있는 모든 사용자

를 설정해주어야한다.

 

또한 구글 스프레드시트의 주소는 csv로 변환된 주소가 아니기 때문에 그냥 사용하면 읽어올 수 없다.

" https://docs.google.com/spreadsheets/d/....../edit?gid=0#gid=0" 

 

해당 주소의 edit ?gid=0#gid=0 를 export?format=csv&gid=0로 변경해주어야한다.

 

해당 주소에서 gid는 현재 시트ID를 뜻한다. 

이는 단순히 0, 1, 2가 아닌 임의의 수이기 때문에 주소를 잘 확인하도록 하자.

728x90
반응형