[언리얼] Lyra Sample Game 실행 흐름

늦잠·2024년 3월 28일
0

시작

언리얼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() :

      • 옵션이나 커맨드라인, 월드의 디폴트 설정 등에서 ExperienceID를 찾아 OnMatchAssignmentGiven 함수를 호출함.
      • Experience모드 대신 디폴트 폰이나, 캐릭터의 능력, UI 등이 저장되어 있는 데이터 에셋.
    • OnMatchAssignmentGiven(ExperienceId , ExperienceIdSource) :

      • 게임 스테이트컴포넌트로 등록되어 있는 ULyraExperienceManagerComponent를 가져와서 SetCurrentExperience(ExperienceId)를 호출해 Experience 등록 시작.
  • ULyraExperienceManagerComponent::

    • SetCurrentExperience(ExperienceId):

      • ULyraAssetManagerExperienceId로부터 Experience경로 추출.
      • 경로로 Experience 에셋을 찾고 이를 CurrentExperience로 지정.
      • StartExperienceLoad 함수를 호출해서 Experience 로드 시작.
    • StartExperienceLoad():

      • ULyraAssetManagerExperience에서 필요한 에셋비동기적(아마두)으로 로드. (나중에 더 공부 필요2)
      • 로드가 끝나면 핸들을 통해 OnExperienceLoadComplete 함수 호출.
    • OnExperienceLoadComplete():

      • Experience와 그 안 ActionSet이 필요한 게임 피처 플러그인의 URL 목록 만듬.
      • UGameFeaturesSubsystem라는 서브시스템을 통해 이 플러그인들 활성화.
      • 활성이 모두 끝났으면 OnExperienceFullLoadCompleted 호출.
    • ULyraExperienceManagerComponent::OnExperienceFullLoadCompleted():

      • ExperienceActionList, 즉 실행할 액션 목록을 등록하고 활성화 시작.
        액션이란 게임 피처가 활성화시키는 행동의 단위 같은 것. 모듈형 게임플레이 속 개념. (공부 더 필요3)
      • ActionSet에 등록되어 있는 액션들도 마찬가지로 등록 및 활성화.
      • 이 과정이 모두 끝나면 Experience 로드가 끝났다. 이후 우선순위 순으로 OnExperienceLoaded_HighPriority, OnExperienceLoaded, OnExperienceLoaded_LowPriority 델리게이트를 차례대로 수행.
  • ALyraGameMode::

    • InitGameState():

      • ULyraExperienceManagerComponentOnExperienceLoadedOnExperienceLoaded 함수 등록.
    • OnExperienceLoaded(CurrentExperience) :

      • 접속에 성공한 player를 스폰 시작.
      • 스폰에 필요한 함수인 SpawnDefaultPawnAtTransform오버라이딩해서 등록된 ExperienceDefaultPawn을 참고하게 함.
  • 이후 레벨에 있는 모든 액터에 대해 한차례 PreInitializeComponents()가 호출되고 이후 각 액터에 대해 InitializeComponents(), PostInitializeComponents() 가 연속적으로 호출됨. (맞나?)

  • 월드, 액터들의 BeginPlay() 시작. 이후 Tick() 루프 시작됨.


위 흐름은 https://ikrima.dev/ue4guide/gameplay-programming/master-engine-flow/master-engine-flow/ 기반으로 적었다.

언리얼 c++ 쪽은 거의 제로베이스인 채로 코드 읽기를 시작해서 틀린 부분이 많을테니 호옥시 이 글 읽는 분 있는 분 있으면 지적 부탁드립니당.

profile
피카

0개의 댓글