✅ ScriptableObject란?
📌 개념 정리
- ScriptableObject는 MonoBehaviour처럼 Unity에서 사용하는 클래스지만,
- 씬에 붙는 컴포넌트가 아니고, 독립적인 데이터 객체야.
- 데이터를 자산(Asset)으로 만들어 저장하고 공유할 수 있는 방식을 제공해.
✅ 언제 사용하나요?
| 여러 객체가 동일한 데이터를 참조할 때 | 예: 스탯, 설정값, 아이템 정보 등 |
| 프리팹이나 코드와 독립적으로 데이터 관리하고 싶을 때 | 설정 변경이 쉽고 유지보수 편함 |
| 인스펙터에서 직접 데이터 입력하고 저장하고 싶을 때 | 커스텀 에디터 연동도 쉬움 |
✅ 간단한 예제: 캐릭터 능력치 데이터 만들기
1. CharacterStats.cs
using UnityEngine;
[CreateAssetMenu(fileName = "NewCharacterStats", menuName = "ScriptableObjects/CharacterStats")]
public class CharacterStats : ScriptableObject
{
public string characterName;
public int maxHP;
public int attackPower;
public float moveSpeed;
}
2. 생성 방법
- Unity 에디터에서 우클릭 → Create → ScriptableObjects → CharacterStats
- 이름을 WarriorStats, MageStats 등으로 지정하고 값 입력
3. 사용하는 스크립트
public class Player : MonoBehaviour
{
public CharacterStats stats;
private void Start()
{
Debug.Log($"{stats.characterName}의 공격력: {stats.attackPower}");
}
}
- Player 오브젝트에 붙이고, stats 필드에 ScriptableObject 자산을 할당하면 끝!
✅ ScriptableObject vs MonoBehaviour
| 씬에 존재 | ❌ (씬에 안 붙음) | ✅ (오브젝트에 붙임) |
| 메모리 효율 | ✅ 매우 좋음 | ❌ 반복 사용 시 비효율 |
| 역할 | 데이터 저장, 설정 | 동작 로직, 이벤트 처리 |
| 재사용 | 여러 오브젝트가 참조 가능 | 오브젝트마다 개별 |
✅ 장점 정리
- ✔️ 씬 독립적 데이터 관리 가능 (게임 밸런스 조정 시 유리)
- ✔️ 프리팹 재사용 시 같은 데이터를 공유할 수 있어 메모리 절약
- ✔️ 버전 관리에 유리 (데이터가 파일로 존재하니까 Git에도 딱!)
- ✔️ 유닛 테스트에 적합
✅ 단점 or 주의사항
- ScriptableObject는 **상태(state)**를 저장하기보단 설정값(config) 저장에 적합함
- 런타임에 값을 바꾸면 에디터에 저장된 자산이 수정될 수도 있으므로 주의
✅ 실생활 비유
- MonoBehaviour는 "게임에 나오는 배우(오브젝트)"
- ScriptableObject는 "그 배우가 참고하는 대본(데이터)"
으음 데이터로 활용하는것은 너무 좋아보인다 처음 이걸 봤을때 왜 이걸 몰랐을까? 싶었다 엄청 유용하게 많이 사용될듯하다 보통 인벤토리 시스템에 많이 사용하는거 같다 스킬/아이템 데이터등등..
간단하게 유니티로 뭐라도 만들어 보자!

대충 요약하자면
📦 전체 구성 요약
1. ScriptableObject 기반 아이템 데이터 관리
- Item_ScriptableObject 클래스 생성
- 인스펙터에서 여러 개의 아이템 데이터를 .asset 파일로 생성 (ItemData1~4)
- 각 아이템은 고유 번호, 이름, 설명, 파워 등의 정보를 가짐
2. 아이템 오브젝트 (Item)
- ItemObject 스크립트 부착
- 각각의 오브젝트가 하나의 ScriptableObject 참조
- Tag는 "Item"으로 지정
3. 플레이어
- WASD 키 입력으로 2D 이동
- Rigidbody2D + Collider2D 구성
- Item과 충돌 시 해당 데이터 획득
4. UI 시스템
- ItemUIManager 스크립트로 Text 컴포넌트 제어
- 아이템 정보 표시 및 초기화 담당
흠..근데 사실 고유 번호는 필요 없었을거같다. 이런식으로 아이템 정보를 저장해서 사용할수있는걸 알게됐다!
나머지 코드
Item_ScriptableObject.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(fileName ="ItemData", menuName = "ScriptableObject/ItemData")]
public class Item_ScriptableObject : ScriptableObject
{
public int itemNum;
public string itemName;
public string iteminfo;
public int itemPower;
}
ItemObject.cs - 아이템에 들어가는 스크립트 - Tag Item으로 추가해줘야한다.
using UnityEngine;
public class ItemObject : MonoBehaviour
{
public Item_ScriptableObject itemData;
}
ItemUIManager.cs 이다 여기서 아이템의 설명과 정보를 출력
using UnityEngine;
using UnityEngine.UI;
public class ItemUIManager : MonoBehaviour
{
public Text nameText;
public Text infoText;
public Text powerText;
public GameObject panel;
private void Start()
{
panel.SetActive(false);
}
public void ShowItemInfo(Item_ScriptableObject item)
{
panel.SetActive(true);
nameText.text = $"이름: {item.itemName}";
infoText.text = $"설명: {item.iteminfo}";
powerText.text = $"파워: {item.itemPower}";
}
public void HideInfo()
{
panel.SetActive(false);
nameText.text = "";
infoText.text = "";
powerText.text = "";
}
}
Player.cs 이다. Item과 닿는다면 UI매니저를 이용해서 아이템의 정보를 받아온다.
using UnityEngine;
public class Player : MonoBehaviour
{
public ItemUIManager uiManager;
private void OnTriggerEnter2D(Collider2D other)
{
if (other.CompareTag("Item"))
{
ItemObject itemObj = other.GetComponent<ItemObject>();
if (itemObj != null && itemObj.itemData != null)
{
uiManager.ShowItemInfo(itemObj.itemData);
}
}
}
private void OnTriggerExit2D(Collider2D other)
{
if (other.CompareTag("Item"))
{
uiManager.HideInfo();
}
}
}
나머지 코드 1개는 PlayerMovement인데 간단하니까 넘어가겠다.
'Unity' 카테고리의 다른 글
| Unity - 2D TopDown에서 캐릭터와 무기의 회전 및 Flip 처리 정리 (1) | 2025.07.23 |
|---|---|
| Unity - (Template vs Template Method Pattern) vs (Class vs Instance) (0) | 2025.07.03 |
| Unity - Update(), FixedUpdate(), LateUpdate() (1) | 2025.07.01 |
| 유니티 머신러닝 2(Unity ML-Agents) (2) | 2024.03.19 |
| 유니티 머신러닝 1(Unity ML-Agents) (13) | 2024.03.19 |