언리얼5와 언리얼 c++ 문법 공부를 본격적으로 시작하기 위해 Lyra Sample Game 프로젝트를 공부해보기로 했다.
샘플이래서 좀 쉬울 줄 알았다.
중간에 이것저것 다른 거 한 시간이 있긴 하지만 한달 넘게 보고 있는데 잘 이해가 안된다...

프로젝트를 처음 열었을 때 게임 모드와 디폴트 폰 등이 비어있어서 당황했다.
게임 모드는 프로젝트 세팅을 통해 LyraGameMode로 지정되어 있었지만 디폴트 폰 등 다른 세부사항은 게임 모드가 아닌 Experience에 위임되어 있었다.
라이라 게임에선 깃발 뺏기나 탑다운 모드 등 여러 가지의 게임 종류가 있었는데 게임 종류마다 Experience를 통해 세부사항을 세팅한다.
이런 방식은 모듈형 게임플레이(Modular gameplay)라는 방식을 라이라 게임에서 변형한 구조인 것 같다.
모듈형 게임플레이에 대해선 따로 공부.
보고 도움됐던 영상 자료들 -
https://www.youtube.com/watch?v=-DLeHXrGPrM
https://www.youtube.com/watch?v=0lEr62LQFpk
다음은 언리얼 엔진이 실행되는 게임 흐름 개요를 기반으로 내가 이해한 라이라 게임이 실행되는 (주로 Experience가 로드 되는) 흐름을 정리한 것이다.
Init() LyraGameInstance::Init() :UGameFrameworkComponentManager를 통해 필요한 초기화 스테이트(InitState)를 등록함. 등록된 모든 피처가 어떤 단계인지 알려주는 역할이라고 이해함. Start()가 호출된 후, 게임인스턴스의 StartGameInstance() 호출됨.게임 모드 - ALyraGameMode::
InitGame():
SetTimerForNextTick로 다음 프레임에 HandleMatchAssignmentIfNotExpectingOne 함수 호출.HandleMatchAssignmentIfNotExpectingOne() :
OnMatchAssignmentGiven 함수를 호출함. OnMatchAssignmentGiven(ExperienceId , ) :ExperienceIdSource
ULyraExperienceManagerComponent를 가져와서 SetCurrentExperience(ExperienceId)를 호출해 Experience 등록 시작.ULyraExperienceManagerComponent::
SetCurrentExperience(ExperienceId):
ULyraAssetManager로 ExperienceId로부터 Experience의 경로 추출.CurrentExperience로 지정.StartExperienceLoad 함수를 호출해서 Experience 로드 시작.StartExperienceLoad():
ULyraAssetManager로 Experience에서 필요한 에셋들 비동기적(아마두)으로 로드. OnExperienceLoadComplete 함수 호출.OnExperienceLoadComplete():
ActionSet이 필요한 게임 피처 플러그인의 URL 목록 만듬.UGameFeaturesSubsystem라는 서브시스템을 통해 이 플러그인들 활성화.OnExperienceFullLoadCompleted 호출.ULyraExperienceManagerComponent::OnExperienceFullLoadCompleted():
ActionList, 즉 실행할 액션 목록을 등록하고 활성화 시작.ActionSet에 등록되어 있는 액션들도 마찬가지로 등록 및 활성화.OnExperienceLoaded_HighPriority, OnExperienceLoaded, OnExperienceLoaded_LowPriority 델리게이트를 차례대로 수행. ALyraGameMode::
InitGameState():
ULyraExperienceManagerComponent의 OnExperienceLoaded에 OnExperienceLoaded 함수 등록.OnExperienceLoaded(CurrentExperience) :
SpawnDefaultPawnAtTransform를 오버라이딩해서 등록된 Experience의 DefaultPawn을 참고하게 함.이후 레벨에 있는 모든 액터에 대해 한차례 PreInitializeComponents()가 호출되고 이후 각 액터에 대해 InitializeComponents(), PostInitializeComponents() 가 연속적으로 호출됨. (맞나?)
월드, 액터들의 BeginPlay() 시작. 이후 Tick() 루프 시작됨.
위 흐름은 https://ikrima.dev/ue4guide/gameplay-programming/master-engine-flow/master-engine-flow/ 기반으로 적었다.
언리얼 c++ 쪽은 거의 제로베이스인 채로 코드 읽기를 시작해서 틀린 부분이 많을테니 호옥시 이 글 읽는 분 있는 분 있으면 지적 부탁드립니당.