
오늘은 유니티의 ScriptableObject (스크립터블오브젝트 이하 SO) 에 대해서 알아보자
ScriptableObject는 이제 나오게 된지 꽤 몇년이 흘렀는데,
로컬환경 구축에 이만한 것이 있을까 싶을정도로
가장 편리하며, 유니티 개발자들에겐 필수적인 요소가 아닐까 싶다.
그 중에서도 오늘은
하나의 데이터 클래스를 SO로 묶고
.json 파일의 export와 import는 하는 editor스크립트도 짜볼까 한다.
실제로 백엔드 통신을 할 적에는 가장 유용했던 부분이다.
게다가 meta파일이 변경되어서 힘들게 쓴 SO가 싹 날라가버리는 불상사도 막을 수 있는 좋은 백업방법이다.
using UnityEngine;
[CreateAssetMenu(fileName = "DataAsset", menuName = "SOSample/DataAsset")]
public class ProtocolData : ScriptableObject
{
}
위 스크립트는 가장 기본적인 ScriptableObject이다.
이 SO를 적게 되면

이런식으로 SO파일을 만들수가 있게 된다.

지금은 아무 내용이 없으니 아무것도 뜨지 않는다.
대충 정보를 적어보도록 하자.
보통의 통신 데이터라고 하면 List인 경우가 많다.
using System;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(fileName = "DataAsset", menuName = "SOSample/DataAsset")]
public class ProtocolData : ScriptableObject
{
public List<DataSample> dataSamples;
}
[Serializable]
public class DataSample
{
public string id;
public string category;
public string name;
}
DataSample이라는 클래스를 하나 만들었고
SO에서 보여주기 위하여 Serializable을 붙여주었다.

이제 기본적으로 우리가 사용하고 보는
SO가나왔다.
이제 이 부분을 좀 더 만져서 위 데이터를 json화 시키거나
json을 가져와서 so에 입력시킬 수 있게도 해보자.
그러려면 Editor스크립트를 작성해 주어야 한다.
json을 다루기 위하여 NewtonSoft.json을 설치를 일단 해준다.


Editor 폴더를 만들고 그 안에 스크립트를 작성해주자.
using System;
using UnityEditor;
using UnityEngine;
[CustomEditor(typeof(ProtocolData))]
public class ProtocolDataEditor : Editor
{
private ProtocolData _target;
private void OnEnable()
{
_target = (ProtocolData)target;
}
}
우리의 첫 CustomeEditor의 기본형을 만들어 주었다. 우리는 ProtoclData.cs 스크립터블 오브젝트를
수정할 것이므로 타겟을 위처럼 설정해준다.
필요한건 Save Load 이다.
그리고 .json파일을 넣어줄 공간도 하나..
[CreateAssetMenu(fileName = "DataAsset", menuName = "SOSample/DataAsset")]
public class ProtocolData : ScriptableObject
{
public TextAsset textAsset; //추가
public List<DataSample> dataSamples;
}
[Serializable]
public class DataSample
{
public string id;
public string category;
public string name;
}
Editor Script
using System;
using System.IO;
using Newtonsoft.Json.Linq;
using UnityEditor;
using UnityEngine;
[CustomEditor(typeof(ProtocolData))]
public class ProtocolDataEditor : Editor
{
private ProtocolData _target;
private void OnEnable()
{
_target = (ProtocolData)target;
}
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
if (_target != null)
{
EditorGUILayout.BeginHorizontal();
if (GUILayout.Button("TextDataLoad") == true)
Load(_target.textAsset.text);
if (GUILayout.Button("TextDataSave") == true)
Save();
EditorGUILayout.EndHorizontal();
}
}
private void Load(string data)
{
if (string.IsNullOrEmpty(data))
return;
_target.dataSamples.Clear();
JArray jArray = JArray.Parse(data);
foreach (var json in jArray)
{
DataSample protocolData = json.ToObject<DataSample>();
_target.dataSamples.Add(protocolData);
}
}
private void Save()
{
if (_target.dataSamples == null || _target.dataSamples.Count == 0)
return;
string path = AssetDatabase.GetAssetPath(_target);
var jArray = new JArray();
foreach (var d in _target.dataSamples)
{
JObject jObject = JObject.FromObject(d);
jArray.Add(jObject);
}
string directory = Path.GetDirectoryName(path);
string assetName = Path.GetFileNameWithoutExtension(path);
string jsonFilePath = Path.Combine(directory, $"{assetName}_sampleData.json");
if (!Directory.Exists(directory))
{
Directory.CreateDirectory(directory);
}
File.WriteAllText(jsonFilePath, jArray.ToString());
AssetDatabase.Refresh();
Debug.Log($"Saved JSON file at: {jsonFilePath}");
}
}
저장의 경우 .json파일을 해당 폴더에 생성하게끔 하였다.
이게 인스펙터창으로 가서 보면 이렇다.

Save버튼을 누르면 DataAsset_sampleData json파일이 떨어진다.

SO의 데이터를 싹 지우고 뽑힌 json파일을 TextAsset에 넣고
Load를 하여도 잘 불러와진다.

이제 meta파일이 변경되어서 SO가 날라가는 불상사를 막을 수도 있다.
'프로그래밍 > Unity' 카테고리의 다른 글
| [유니티] Unity - AAR로 안드로이드 Toast와 알림메시지 (notification)구현해보기. (4) | 2025.04.08 |
|---|---|
| [유니티] Unity - DI (Dependency Injection) VContainer 간단사용법 (0) | 2025.04.07 |
| [유니티] Unity - Parallel 병렬처리로 반복작업 속도 향상시키기 (0) | 2024.12.18 |
| [유니티] Unity - 코루틴 리턴값 받기와 Action에 대하여. (6) | 2024.12.13 |
| [유니티] Unity WebGL - React.js와 쌍방향 통신하기 (2) | 2024.12.11 |