[유니티] Unity - ScriptableObject 잘 사용하기 (feat: json Editor)

2024. 12. 27. 12:19·프로그래밍/Unity
반응형
BIG

 

오늘은 유니티의 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가 날라가는 불상사를 막을 수도 있다.

 

 

반응형
BIG
저작자표시 비영리 동일조건 (새창열림)

'프로그래밍 > 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
'프로그래밍/Unity' 카테고리의 다른 글
  • [유니티] Unity - AAR로 안드로이드 Toast와 알림메시지 (notification)구현해보기.
  • [유니티] Unity - DI (Dependency Injection) VContainer 간단사용법
  • [유니티] Unity - Parallel 병렬처리로 반복작업 속도 향상시키기
  • [유니티] Unity - 코루틴 리턴값 받기와 Action에 대하여.
dduR
dduR
글쓰는 프로그래머 뚜르입니다 :)
    백만원으로 1억 만들기
    상담 신청하기
    »
    • 분류 전체보기
      • 공지사항
      • 프로그래밍
        • Flutter
        • Backend
        • Unity
        • Frontend
      • 재테크 부수입
      • 편집툴
        • 포토샵
        • 애프터이펙트
      • 이공계지식
        • 미분적분학
        • 공업수학
        • IT
  • 블로그 메뉴

    • 홈
    • 방명록
  • dduR
    부수익 창출에 목마른 개발자
    dduR
  • 링크

  • 인기 글

  • 반응형
  • hELLO· Designed By정상우.v4.10.2
dduR
[유니티] Unity - ScriptableObject 잘 사용하기 (feat: json Editor)
상단으로

티스토리툴바