ScriptableObject
유니티에서 제공하는 데이터 컨테이너이다.
저장된 데이터를 여러 오브젝트들이 공유해서 사용하는 방식이기 때문에,
값이 정해진 데이터를 여러 오브젝트가 복사해서 사용하며 생기는 불필요한 메모리 사용을 막을 수 있다.
데이터와 실제 게임 코드를 분리하여 직렬화 할 수 있으며, 유니티 에디터에서 수정 및 관리가 용이한 장점이 있다.
https://unity.com/kr/how-to/architect-game-code-scriptable-objects
위 문서를 참고하여 아래와 같은 샘플 코드를 작성해보았다.
우선, 같이 PlayerData 라는 ScriptableObject 객체를 만들었다.
using UnityEngine;
[CreateAssetMenu]
public class PlayerData : ScriptableObject, ISerializationCallbackReceiver
{
[SerializeField]
private int initialHp; // 인스펙터에서 10으로 입력함.
public int Hp { get; set; }
public int MaxHp { get; private set; }
/// <summary>
/// 역직렬화된 후에 호출
/// </summary>
public void OnAfterDeserialize()
{
Hp = initialHp;
MaxHp = initialHp;
}
/// <summary>
/// 직렬화되기 전에 호출
/// </summary>
public void OnBeforeSerialize()
{
}
}
@warning
ISerializationCallbackReceiver 는 객체가 직렬화 될 때/역직렬화 될 때 특정 콜백을 실행할 수 있게 해주는 인터페이스이다.
CreateAssetMenu 속성을 class 앞에 붙여 에디터 메뉴에서 PlayerData를 생성할 수 있도록 하였다.
initialHp를 SerializeField속성을 붙여 인스펙터상에서 수정할 수 있도록 하였고, 다른 객체에서는 접근 불가하도록 하였다.
다른 객체에서는 Hp, MaxHp값만 참조하여 사용하며, 역직렬화 될 때 해당 값을 초기화 해주도록 작성하였다.
아래 코드에서 Player객체는 PlayerData의 Hp값을 변경하고 있고, HpBar 객체는 PlayerData의 Hp값을 참조해 UI를 갱신한다.
using UnityEngine;
public class Player : MonoBehaviour
{
[SerializeField]
private PlayerData playerData;
void Update()
{
// 마우스 왼쪽 버튼 누를 때 마다 HP 감소.
if (Input.GetMouseButtonDown(0))
{
playerData.Hp -= 1;
}
}
}
using UnityEngine;
using UnityEngine.UI;
public class HpBar : MonoBehaviour
{
[SerializeField]
private PlayerData playerData;
[SerializeField]
private Image bar;
private void Update()
{
bar.fillAmount = playerData.Hp / (float)playerData.MaxHp;
}
}
이렇게 마우스 왼쪽 클릭할 때 마다 Hp값이 변경되어 HpBar에도 변경된 Hp값으로 UI 표시를 해주고 있지만
역직렬화 할 때 Hp값이 인스펙터 상에서 입력한 InitialHp의 값으로 초기화가 되게 된다.
예시를 Hp로 작성하긴 했지만, ScriptableObject는 런타임 시에 변경한 값이 저장되지 않으므로
실제 사용 시엔 값이 바뀌지 않는 아이템이나 맵 데이터 등을 저장하는데에 쓰면 좋을 것 같다.
'Unity' 카테고리의 다른 글
[Unity] SelectionBase Attribute / 씬뷰에서 우선 선택될 GameObject 지정해주기 (0) | 2024.07.24 |
---|---|
[Unity] Game Scene 스크린샷 찍기 / Mac, Window 저장된 폴더 열기 (0) | 2024.07.20 |
[Unity] GameObject 생성시 Position (0, 0, 0) 자동 초기화, Scene View Preferences (0) | 2024.06.27 |