ScriptableObject

강성현
∙∙조회 2
ScriptableObject

ScriptableObject의 개념과 용도

게임 오브젝트에 컴포넌트로 붙지 않고 프로젝트의 에셋으로 존재하는 데이터 그릇입니다. -> 데이터 에셋

 

데이터 에셋의 용도

값을 프로젝트 안에 에셋으로 넣어 두고, 게임이 실행되는 동안 그 값을 읽어 쓰는데 씁니다.

  • 데이터 에셋을 쓰기 위해 필요한 요소 3가지
  1. 클래스 스크립트
  2. 데이터 에셋
  3. 컴포넌트

 


1. ScriptableObject 스크립트

  • 상속 대상 ==MonoBehaviour== 를 ==ScriptableObject== 로 바꿉니다.
  • Start와 Update 이벤트함수는 지웁니다.
unity
using UnityEngine;

public class EnemyStats : ScriptableObject  
{  
}

 

 


2. CreateAssetMenu

Create 메뉴에 항목을 표시해주는 기능입니다.

속성하는 일이 예의 값
fileName새로 만든 에셋의 기본 파일 이름NewEnemyStats
menuNameCreate 메뉴에 보이는 이름. /로 나누면 하위 메뉴가 됩니다AIProgramming/Enemy Stats
unity
using UnityEngine;

[CreateAssetMenu(fileName = "NewEnemyStats", menuName = "AIProgramming/Enemy Stats")]  
public class EnemyStats : ScriptableObject  
{  
    [SerializeField] private int _maxHp;  
    [SerializeField] private float _detectRange;  
    [SerializeField] private float _attackRange;  
    [SerializeField] private float _meterPerSecond;  
    [SerializeField] private float _attackInterval;  
    [SerializeField] private string _name;

    public int MaxHp => _maxHp;  
    public float DetectRange => _detectRange;  
    public float AttackRange => _attackRange;  
    public float MeterPerSecond => _meterPerSecond;  
    public float AttackInterval => _attackInterval;  
    public string Name => _name;  
}

 

2-1 ) 에셋 인스펙터

인스펙터 맨 위에 에셋이 어느 클래스로 만들어졌는지 보여주는 ==Script== 칸, 그 아래에 ==field== 칸이 있습니다.

인스펙터에서 넣은 값은 에셋 파일에 저장되어 에디터를 다시 켜도 남습니다.

 

 


3.MonoBehaviour와의 차이

  • MonoBehaviour와 ScriptableObject 상속 계층

==ScriptableObject==는 ==Component== 아래가 아니라 ==Object== 바로 아래에 있기 때문에 ==Component== 과 관련된 ==transform== 등을 적으면 컴파일 오류가 납니다.

MonoBehaviour

ScriptableObject

붙는 곳

게임 오브젝트에 컴포넌트로 붙음

붙지 않음. 프로젝트의 에셋

에디터에서 만드는 방법

인스펙터의 Add Component

Project 창의 Create 메뉴

코드로 만드는 방법

AddComponent<T>()

ScriptableObject.CreateInstance<T>()

보이는 곳

Hierarchy에서 고른 오브젝트의 인스펙터

Project 창에서 고른 에셋의 인스펙터

Start·Update

불림

불리지 않음

Transform

있음

없음

 

 


4. 에셋 참조와 공유

4-1) 에셋을 받는 칸

==SciptableObject==는 Create로 만든 에셋을 컴포넌트의 칸으로 받아 사용합니다.

unity
using UnityEngine;

public class AssetEnemy : MonoBehaviour  
{  
    [SerializeField] private EnemyStats _stats;

    private void Start()  
    {  
        PrintStats();  
    }

    private void PrintStats()  
    {  
        Debug.Log($"AssetEnemy: {_stats.Name} 체력 {_stats.MaxHp} 감지 {_stats.DetectRange} 속도 {_stats.MeterPerSecond}");  
    }  
}

 

 

4-2) 한 에셋의 공유

값을 바꾸게 된다면 데이터 에셋은 같은 ==SciptableObject== 를 가지고 있다면 모두 바뀐 값을 씁니다.

데이터 에셋은 실행중에도 바꾼 값이 모두에게 적용됩니다.

[Serializable] 일반 클래스 칸

ScriptableObject 칸

칸의 모양

펼치면 필드마다 칸이 나옴

펼쳐지지 않고 에셋 하나를 가리킴

값이 있는 곳

그 컴포넌트 안

가리키는 에셋 안

오브젝트가 셋이면

값이 세 벌

에셋 하나를 셋이 가리킴

 

4-3) 함께 쓰는 값과 개체마다의 값

값의 성격

예

두는 곳

같은 종류면 모두 같은 값

최대 체력, 감지 거리, 공격 거리, 초당 이동 거리, 공격 간격, 이름

데이터 에셋

개체마다 달라지는 값

현재 체력, 위치, 쫓아갈 대상

컴포넌트 필드