유니티는 ScriptableObject 라는 독특한 형태의 데이터 컨테이너를 제공합니다. 이 글에서는 유니티 공식 페이지에서 ScriptableObject 의 활용법으로 올라온 모듈형 디자인의 한 예제로 소개된 방식을 직접 구현해 보도록 하겠습니다.
들어가기에 앞서서 이 글에서는 ScriptableObject 의 다음 특징을 이용합니다.
- 변수 값은 자동으로 Serialization 기능을 통해 디스크에 저장됩니다. 이 값은 런타임 시에 변경돼도 저장됩니다.
- 변수 값은 모든 객체에서 동일하게 유지됩니다.
공식 페이지의 문서는 다음의 링크를 참조하시면 됩니다.
|
스크립터블 오브젝트로 코드를 설계하면 코드를 유연하고 간편하며 디버깅에 용이한 상태로 유지할 수 있습니다.
unity.com
▶ 준비사항
예제로 사용한 에셋은 여기를 클릭하시면 무료로 받을 수 있습니다. 다운로드 후 프로젝트에 import 해 주세요.
▶ 캐릭터에 HP Bar UI 만들기
- Project 창에서 경로 [Assets > SunnyLand Artwork > Sprites > player > idle] 로 이동합니다.
- 이미지 "player-idle-1" 를 클릭하고 Inspector 창에서 Pixels Per Unit 을 33 으로 설정하고 [Apply] 를 클릭합니다.
- 이미지 "player-idle-1" 을 Hierarchy 창으로 드래그 하고 이름을 Player 로 변경합니다.
- Player 객체를 선택하고 마우스 우클릭 [UI > Canvas] 를 선택해 자식 객체를 만들어 줍니다.
- Canvas 객체를 다음과 같이 설정합니다.
- 먼저 Render Mode 를 World Space 로 변경합니다.
- Rect Transform 의 Pos X / Pos Y / Width / Height 를 모두 0 으로 변경합니다.
- Event Camera 에 Main Camera 를 연결합니다.
- Canvas 객체를 선택하고 마우스 우클릭 [UI > Image] 를 선택해서 자식으로 Image 객체를 생성하고 이름을 HealthBar 로 변경합니다.
- HealthBar 의 RectTransform 값을 다음과 같이 설정합니다.
- HealthBar의 Image 컴포넌트의 Color 를 검은 색으로 설정합니다.
- HealthBar의 자식 객체로 다시 UI > Image 를 생성하고 이름을 Fill 로 변경합니다.
- Fill 의 RectTransform 을 다음과 같이 설정합니다.
- Image 컴포넌트의 Image Type: Filled 를 사용하기 위해선 Source Image 필드에 이미지를 연결해 주어야 합니다.
- Project 창에서 Assets 밑에 Sprites 폴더를 만들고 그 안에 마우스 우클릭 [Create > 2D > Sprites > Square] 를 선택합니다.
- 생성된 Square 이미지를 Fill 객체의 Image 컴포넌트에 연결하고 다음과 같이 설정합니다.
- Color = Red / Image Type = Filled / Fill Method = Horizontal 로 변경합니다.
▶ ScriptableObject 만들기
- Proejct 창에서 Assets 밑에 Scripts 폴더를 생성합니다.
▷ FloatVariable
- Scripts 폴더에서 마우스 우클릭 [Create > C# Script] 로 새로운 스크립트를 생성하고 이름을 FloatVariable 로 변경하고 코드를 다음과 같이 수정합니다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu]
public class FloatVariable : ScriptableObject, ISerializationCallbackReceiver
{
// 초기 설정 값
public float initValue;
// 실제 게임 실행 시 사용할 값
// NonSerialized 이기 때문에 runtimeValue 는
// 디스크에 저장되지 않습니다.
[System.NonSerialized]
public float runtimeValue;
// 디스크에 저장된 값을 역직렬화로 initValue 로 가져온 후
public void OnAfterDeserialize()
{
runtimeValue = initValue;
}
public void OnBeforeSerialize() { }
}
- Project 창에서 경로 [Assets > Scripts] 에서 마우스 우클릭 [Create > Float Variable] 을 선택해서 새로운 FloatVariable을 생성하고 이름을 FloatHP 로 변경합니다.
- FloatHP 를 선택하고 Inspector 창에서 InitValue 값을 100 으로 설정합니다.
▷ GameEvent
- Scripts 폴더에서 마우스 우클릭 [Create > C# Script] 로 새로운 스크립트를 생성하고 이름을 GameEvent 로 변경한 후 코드를 다음과 같이 수정합니다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu]
public class GameEvent : ScriptableObject
{
// 발생 시킨 이벤트를 수신할 listener 목록
private List<GameEventListener> listeners = new List<GameEventListener>();
// 이벤트 발생
public void Raise()
{
for (int i = listeners.Count - 1; i >= 0; i--)
listeners[i].OnEventRaised();
}
// listener 등록
public void RegisterListener(GameEventListener listener)
{
listeners.Add(listener);
}
// 등록된 listener 해제
public void UnregisterListener(GameEventListener listener)
{
listeners.Remove(listener);
}
}
* 이 코드까지 작성하면 GameEventListener 가 없기 때문에 컴파일 에러가 발생합니다.
▶ GameEventListener
- Scripts 폴더에서 마우스 우클릭 [Create > C# Script] 로 새로운 스크립트를 생성하고 이름을 GameEventListener 로 변경한 후 코드를 다음과 같이 수정합니다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
public class GameEventListener : MonoBehaviour
{
public GameEvent Event;
public UnityEvent Response;
// 스크립트가 활성화 되면 GameEvent 에 등록합니다.
private void OnEnable()
{
Event.RegisterListener(this);
}
// 스크립트가 비활성화 되면 GameEvent 에서 해제합니다.
private void OnDisable()
{
Event.UnregisterListener(this);
}
// 유니티 에디터에서 UnityEvent에 등록한 함수를 호출합니다.
public void OnEventRaised()
{
Response.Invoke();
}
}
- Project 창에서 경로 [Assets > Scripts] 에서 마우스 우클릭 [Create > GameEvent] 을 선택해서 새로운 GameEvent를 생성하고 이름을 HPEvent 로 변경합니다.
여기 까지가 SciptableObject 와 유니티 이벤트를 이용한 모듈화를 위한 기본 코드들입니다.
위 코드들의 흐름은 다음과 같습니다.
- 캐릭터의 HP (FloatHP 의 runtimeValue) 가 변하면 GameEvent 의 Raise() 함수 호출
- GameEvent 의 Raise() 함수에서 등록된 GameEventListener 의 OnEventRaised() 함수 호출
- GameEventListener 의 OnEventRaised() 함수에서 UnityEvent에 등록한 스크립트의 함수 호출 (Response.Invoke())
- 스크립트의 함수에서 FloatHP의 runtimeValue 값에 따라 HP Bar UI 갱신
자세한 구현은 2부에서 진행하도록 하겠습니다.
[유니티 활용] ScriptableObject 로 HP Bar 만들기 - #2
이 글은 "ScriptablObject 로 HP Bar 만들기 - #1" 에 이어서 작성하는 글입니다. ▶ PlayerObj 스크립트 작성 Hierarchy 창에서 Player 객체를 선택하고 PlayerObj 이름으로 새 스크립트를 생성합니다. PlayerObj 의
ugames.tistory.com
'게임 프로그래밍 > 유니티 활용' 카테고리의 다른 글
[유니티 활용] ScriptableObject 를 이용한 스킬 시스템 만들기 (7) | 2023.01.01 |
---|---|
[유니티 활용] ScriptableObject 로 HP Bar 만들기 - #2 (3) | 2022.12.30 |
[유니티 활용] StateMachine 과 몬스터 AI (2) | 2022.12.26 |
[유니티 활용] 부드러운 카메라 이동과 경계 값 설정 (0) | 2022.12.25 |
[유니티 활용] BlendTree 를 이용한 2D 점프 애니메이션 (2) | 2022.12.23 |
댓글