나만의 작은 도서관
[TIL][C++] 250723 MMO 서버 개발 64일차: 언리얼 GameMode, 유니티 지식으로 알아보는 언리얼 본문
Today I Learn
[TIL][C++] 250723 MMO 서버 개발 64일차: 언리얼 GameMode, 유니티 지식으로 알아보는 언리얼
pledge24 2025. 7. 24. 00:23주의사항: 해당 글은 일기와 같은 기록용으로, 다듬지 않은 날것 그대로인 글입니다.
언리얼 GameInstance는 게임 내 유일하다.
- 언리얼의 게임 인스턴스는 맵의 전환과 별개로 독립적으로 게임 내 단 한 개만 존재한다.
- 게임이 시작될 때 한 번 생성되고 게임이 완전히 종료되면 그때 사라진다.
- 맵이 바뀌어도 사라지지 않는다.
- ⇒ 게임 전체에서 공유되는 데이터를 관리하는데 적합하다.
활용 예시
- 플레이어의 전체 진행도, 레벨, 경험치
- 게임 설정값(그래픽, 사운드 옵션)
- 맵들 간 전달해야 하는 데이터
- 세이브/로드 시스템
언리얼 GameMode
- 언리얼에서 게임 모드(GameMode)는 게임의 규칙을 결정하고 정보를 처리하는 **“액터(Actor)”**이다.
- 게임 모드는 아래와 같은 규칙들을 결정한다.
- 플레이어가 게임에 진입하는 방식(ex. 스폰 위치)
- 액터 간의 상호작용 처리 방식
- 최대 플레이어 수, 관전자 수
- 게임 일시정지 기능의 가능 여부 또는 처리 방식
- 레벨 간의 전환, 게임 내 시네마틱 모드 시작 여부
게임 모드 활용하는 법: 맵 시작 프로세스
- 게임 모드는 이름 그대로 게임 모드를 설정하는 것이다. 따라서, 데스매치, 점령 전 등 “하나의 맵에서도 여러 모드로 플레이”하는 경우에 각 모드에 대한 규칙을 설정하고, 맵에 해당 모드를 적용하는 방식으로 사용된다.
- 맵에 게임 모드를 설정하면, 해당 맵으로 전환될 때부터 벗어날 때까지 설정한 게임 모드가 유지된다. 유용하게 사용할 수 있는 부분은 바로 게임 시작 시점이다.
- 게임 모드의 StartPlay는 BeginPlay보다 늦게 실행되며, 주로 게임 시작 관련 로직을 처리할 때 사용한다. 즉, 맵에 배치되어 있지 않지만 시작과 동시에 차례대로 생성되거나 초기화해야 하는 로직이 있다면 관련 로직을 StartPlay에 몰아넣으면 된다.
유니티 지식으로 알아보는 언리얼
- 유니티의 Awake + Start 로직 = 언리얼의 BeginPlay
- BeginPlay는 각 오브젝트가 생성되었을 때 실행하는 로직이다.
- 유니티의 Update = 언리얼의 Tick
- 매 프레임마다 호출되는 함수
- 실행 순서
- 생성자 → BeginPlay() → Tick(매 프레임마다)
- 유니티 프리팹(prefab) = 언리얼 블루프린트(BP)
- 각각은 재사용 가능
- 한 객체를 생성하고 관리하는 기능.
조금 멍청한 실수: 소스 코드를 작성했다고 맵에 자동으로 들어가지는 않는다.
- 당연하게도 C++로 클래스를 작성하고 블루프린트 설정 없이 그대로 실행해도 맵에 적용되지 않는다. 작성한 코드는 그저 기반에 될 뿐, 해당 클래스를 블루프린트로 만들거나 해당 클래스를 상속한 오브젝트를 배치해야 한다.
- 모든지 BP를 통해야만 코드가 작동한다는 점을 잊지 말자.
- 유니티 기준으로, 스크립트를 짜놓고 프리팹을 Instantiate 하는 오브젝트를 넣어놓거나, 게임 오브젝트를 맵에 배치하는 것을 하지 않은 것과 다름없다는 것이다.
부모 클래스 바꾸기
- 가끔 잘못 상속받은 상태로 블루프린트를 만들어서 다 만들어진 블루프린트를 버려야 하나 고민한 적이 있었는데, 그럴 필요가 없다.
- 그저 블루프린트에 들어가서 클래스 세팅 _> 디테일에서 바꾸면 된다.
UPROPERTY(meta = (BindWidget))
- 위젯에 위 매크로 함수로 짜인 클래스를 상속받아 만들면, 위젯에 있는 각 UI 컴포넌트의 이름과 c++ 코드에 있는 이름과 동일해야 한다.
- 동일하게 안 하면 블루프린트에서 컴파일이 되지 않는다.
- 제대로 작성했다면, UI 컴포넌트가 C++ 변수와 바인딩되어서 C++ 코드에서 활용할 수 있다.
- ⇒ 런타임에 접근하여 사용 가능!
- 블루프린트 쓰기 싫어서 알아본 내용인데, 꽤 유용한 듯하다.
UFUNCTION(AddDynamic)
- 해당 지정자는 언리얼 엔진에서 델리게이트(Delegate)에 함수를 동적으로 바인딩할 때 사용하는 매크로이다.
주요 특징
- 델리게이트 바인딩용 매크로
- 런타임에 함수를 델리게이트에 연결
- 주로 이벤트 처리나 콜백 함수 등록에 활용
사용 예시
// 델리게이트 선언
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnHealthChanged, float, NewHealth);
// 함수를 델리게이트에 바인딩
HealthComponent->OnHealthChanged.AddDynamic(this, &AMyCharacter::HandleHealthChanged);
// 바인딩될 함수는 UFUNCTION으로 선언되어야 함
UFUNCTION()
void HandleHealthChanged(float NewHealth);
왜 필요한가:
- C++의 일반 함수 포인터와 달리, 언리얼의 리플렉션 시스템과 연동
- 블루프린트에서도 접근 가능
- 직렬화(Serialization) 지원
- 가비지 컬렉션과 안전하게 동작
주의사항:
- AddDynamic으로 바인딩하려는 함수는 반드시 UFUNCTION()으로 선언되어야 한다
- 주로 DECLARE_DYNAMIC_DELEGATE 계열 델리게이트와 함께 사용된다.