[Unity, C#] ScriptableObject - 스크립터블 오브젝트

2025. 8. 2. 18:37·Unity,C#/Unity 정보
728x90

■ ScriptableObject

[Scriptable Object]

스크립터블 오브젝트(Scriptable Object)는 유니티에서 제공하는 Mono와 다른 경량 데이터 컨테이너 클래스이다.

  • 말 그대로 스크립팅 가능한 Object, 즉 코드로 정의된 데이터 저장용 객체를 의미한다.

스크립터블 오브젝트는 씬에 존재하지 않으며, 데이터를 독립적으로 저장하고 재사용 할 수 있는 “에셋 파일(.asset)”로 저장된 직렬화 가능한 데이터 객체이다.

스크립터블 오브젝트는 다음과 같은 상황에서 사용된다.

  1. 게임 내 설정값 관리.
  2. 무기, 아이템, 능력치 등 고정된 데이터를 관리할 때.
  3. 동일한 데이터를 여러 오브젝트가 공유해야 할 때.
  4. 씬이 변경되어도 데이터가 유지되어야 할 때.

 

▼ 몬스터에 관련된 데이터 클래스를 만들 때, Monobehaviour와 Scriptable Object는 다음과 같은 차이점이 있다.

  Monobehaviour  Scriptable Object
참조 객체 각 GameObject 마다 개별 인스턴스. 여러 객체가 하나의 데이터 인스턴스 공유.
값 변경 시 각자만의 값이 바뀜. (개별 상태 유지) 모든 객체에 반영.
저장 위치 씬 혹은 프리팹 내부. 프로젝트 창의 .asset 파일

 

1. 직렬화(Serialization) 란?

일반적으로 직렬화는 복잡하고 다양한 구조를 가진 데이터를, 순차적인 바이트 흐름(데이터 스트림)으로 변환하는 작업을 의미한다.

  • 객체의 변수들이 연속된 주소에 없을 수 있음.
  • 포인터, 참조 등은 메모리 내부 전용 정보라 외부 저장 불가.

그렇기에 파일에 저장하거나 네트워크로 전송하려면 이 메모리 구조를 일렬로 정리해야 하는데, 이 과정을 바로 직렬화(Serialization)라고 한다.

[System.Serializable]
public class MonsterData
{
    public string name;   // 문자열은 길이 + 문자들
    public int hp;        // 4바이트
    public float speed;   // 4바이트
}

유니티에서의 직렬화도 위와 같은 데이터를 저장하기 위해선

          → name, hp, speed를 정해진 순서로, 포맷에 맞게 바이트로 변환.

          → 이 과정은 유니티의 직렬화 시스템이 자동으로 처리한다.

 

스크립터블 오브젝트는 내부 변수 데이터를 자동으로 직렬화하여 저장하고, 사용할 때는 역직렬화(Deserialization)하여 메모리에서 사용할 수 있도록 한다.

 

■ 스크립터블 오브젝트 생성

using UnityEngine;

[CreateAssetMenu(fileName = "MonsterData", menuName = "Scriptable Objects/MonsterData",
	 order = 1))]
public class MonsterData : ScriptableObject
{
    [SerializeField] private string monsterName;
    [SerializeField] private float hp;
    [SerializeField] private float damage;
    [SerializeField] private int lv;

    public string MonsterName => monsterName;
    public float Hp => hp;
    public float Damage => damage;
    public int Lv => lv;
}

스크립터블 오브젝트는 ScriptableObject 클래스를 상속받아 정의한다.

프로젝트 창에서 에셋 파일(.asset)을 생성하기 위해 [CreateAssetMenu] 어트리뷰트를 사용한다.

 

▶ [CreateAssetMenu] 어트리뷰트

  • fileName = 생성되는 .asset 파일의 기본 이름

  • menuName = 프로젝트 창에서 우클릭 → Create 시 표시될 메뉴 경로
  • order = 메뉴 항목의 정렬 순서. (숫자가 낮을수록 위에 표시)
using UnityEngine;

public class Monster : MonoBehaviour
{
    [SerializeField] private MonsterData data;

    private void Start()
    {
        Debug.Log(data.MonsterName);
        Debug.Log(data.Hp);
        Debug.Log(data.Damage);
        Debug.Log(data.Lv);
    }
}

[스크립터블 오브젝트]

스크립터블 오브젝트를 사용하려면, 해당 컴포넌트에서 스크립터블 오브젝트 클래스 타입의 변수를 선언한 후, 인스펙터에서 .asset 파일을 드래그하여 연결하면 된다.

 

[.asset 값 변화]

MonsterData.asset 처럼 하나의 스크립터블 인스턴스를 여러 오브젝트가 공유하면, 해당 .asset의 값을 변경했을 때 모든 참조 대상에게도 즉시 반영된다.

즉, 하나의 데이터를 여러 프리팹이나 게임 오브젝트가 공통으로 사용할 수 있는 구조가 된다.

  • 런타임 중 스크립터블 오브젝트의 값을 수정하면, 에디트 모드로 돌아와도 변경 내용이 유지된다. (.asset 파일 자체가 수정되기 때문)

 

스크립터블 오브젝트는 변하지 않는 “설정 데이터”를 저장.

private float currentHp;

private void Start()
{
    currentHp = data.Hp; // ScriptableObject로부터 초기값만 받아옴
}

hp, lv처럼 게임 플레이 중 변경되는 상태 값을 스크립터블 오브젝트에 그대로 저장하면 참조하는 모든 오브젝트의 값이 바뀌는 부작용이 발생한다.

 

따라서, 이런 상태 값이 필요한 경우에는

  • 초기값만 스크립터블 오브젝트에서 불러오고, 런타임에서는 MonoBehaviour나 별도의 상태 클래스에 복사하여 사용한다.
MonsterData clone = Instantiate(originalMonsterData);
clone.hp = 50;  // 이제 이건 독립된 값

혹은 위와 같이 스크립터블 오브젝트 자체를 복사하여 개별로 사용할 수 있다.

728x90

'Unity,C# > Unity 정보' 카테고리의 다른 글

[Unity, C#] EditorWindow - 커스텀 에디터 윈도우  (1) 2025.08.02
[Unity, C#] Editor - 커스텀 인스펙터  (0) 2025.08.02
[C#] LINQ(Language Integrated Query)  (1) 2025.06.27
[Unity] Coroutine(코루틴) 파헤치기  (4) 2025.05.30
'Unity,C#/Unity 정보' 카테고리의 다른 글
  • [Unity, C#] EditorWindow - 커스텀 에디터 윈도우
  • [Unity, C#] Editor - 커스텀 인스펙터
  • [C#] LINQ(Language Integrated Query)
  • [Unity] Coroutine(코루틴) 파헤치기
브라더스톤
브라더스톤
유티니, C#과 관련한 여러 정보를 끄적여둔 블로그입니다. Email : dkavmdk98@gmail.com
  • 브라더스톤
    젊은 프로그래머의 슬픔
    브라더스톤
  • 전체
    오늘
    어제
    • 개발 노트 (26)
      • Unity,C# (26)
        • Unity 정보 (5)
        • 알고리즘 (10)
        • 자료구조 (2)
        • 절차적생성(PCG) (9)
      • C++ (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    절차적지형생성
    절차적 던전 생성
    PerlinNoise
    정렬알고리즘
    CustomEditorWindow
    BSP
    절차적던전생성
    알고리즘
    CustomWindow
    Custom Inspector
    binary space partitioning
    C#
    이진공간분할
    커스텀 인스펙터
    pcg
    최단경로찾기
    자료구조
    unity
    이진공간분할법
    커스텀 윈도우
  • 최근 댓글

  • 최근 글

  • 250x250
  • hELLO· Designed By정상우.v4.10.3
브라더스톤
[Unity, C#] ScriptableObject - 스크립터블 오브젝트
상단으로

티스토리툴바