인프런 영문 브랜드 로고
인프런 영문 브랜드 로고

인프런 커뮤니티 질문&답변

김민재님의 프로필 이미지

작성한 질문수

이득우의 언리얼 프로그래밍 Part1 - 언리얼 C++의 이해

14강 언리얼 오브젝트 관리 II - 패키지

생성자에서 로딩과, Init함수에서 로딩의 차이점이 궁금합니다.

작성

·

56

0

안녕하세요.

애셋을 로딩할 때 생성자와 Init함수의 차이 때문에 사용 API가 달라져야하는 이유가 궁금합니다.

 

생성자 단계에서 단순히 LoadObject<UStudent>(nullptr, *TopSoftObjectPath); 를 통해 로딩할 순 없는 정확한 이유를 모르곘습니다...! 또한 Init()의 LoadStudentObject()에서 LoadObject<>()로 TopStudent를 리턴 받은 후에, 포인터에 대한 nullptr 체크를 따로 하지 않는 이유는 LoadObject또한 해당 애셋이 무조건 있어야 올바르게 동작하기 때문인가요?

답변 2

0

이득우님의 프로필 이미지
이득우
지식공유자

생성자는 플레이가 시작되기 전 준비단계에서 호출된다고 생각하면 좋습니다.
언리얼 엔진 기반의 모든 앱은 사전 로딩작업이 들어갑니다. 이 때 CDO가 만들어지고, 생성자가 호출됩니다. 언리얼 엔진 에디터를 시작할 때 %가 올라가는게 그런 이유라고 보면 될 것 같아요.
반면 BeginPlay는 사전 준비가 모두 끝나고 플레이가 시작될 때 호출됩니다. 즉 콘텐츠 재생이 시작될 때 호출되는 것이지요.
둘은 동작하는 메커니즘이 다르기 때문에 다른 API를 사용한다고 보면 될 것 같아요.
즉 CreateDefaultSubObject는 사전 준비를 위한 기본 오브젝트를 생성하는 API고 LoadObject는 실제 콘텐츠에 기여하는 객체를 생성하는 API입니다.

0

인프런 AI 인턴님의 프로필 이미지

안녕하세요, 김민재님. 인프런 AI 인턴입니다.

언리얼 엔진에서 애셋을 로딩할 때, 생성자 단계와 Init 함수에서의 로딩 방식의 차이점은 주로 엔진의 초기화 상태와 관련이 있습니다.

생성자 단계에서의 로딩

생성자에서는 아직 엔진의 모든 서브시스템이 초기화되기 전 단계이기 때문에, LoadObject<>()와 같은 런타임 로딩 API를 사용하는데 제한이 있습니다. 이는 생성자에서 직접적인 리소스 접근은 엔진 상태와 관계없이 로드되기 때문에 활성화되어 있는 모든 관련 시스템 또는 콘텐츠가 준비되지 않은 상태에서 로드를 시도할 수 있어 문제가 발생할 수 있다는 점에서 비롯됩니다.

Init 함수에서의 로딩

반면, Init 함수는 엔진이 충분히 초기화된 후 호출됩니다. 이 시점에는 모든 서브시스템이 정상적으로 준비되어 있으므로 런타임 로딩 API를 안전하게 사용할 수 있습니다. 이 때문에 LoadStudentObject()에서는 LoadObject<>()를 통해 애셋을 로드하는 것이 가능합니다. 이 경우, 엔진이 필요한 종속성을 모두 충족시킨 환경에서 안전하게 로딩이 가능합니다.

nullptr 체크

LoadObject() 함수는 지정한 경로에 해당하는 애셋이 존재하지 않을 경우, nullptr을 반환하게 됩니다. 일반적으로 로딩 이후에 포인터에 대한 nullptr 체크를 수행하여 성공 여부를 확인하는 것이 좋습니다. 하지만 특정 상황에서는 이미 애셋이 존재한다고 확신할 수 있어 체크를 생략하는 경우도 있습니다. 이는 기본적으로 애셋 경로의 유효성이 선행되어 보장되며, 경로가 잘못되거나 애셋이 존재하지 않는 경우에는 Null Pointer 예외가 발생할 수 있으니 주의해야 합니다.

관련 유사 질문 URL

다음 링크를 통해 더 많은 정보와 예제를 확인하실 수 있습니다:
- 에셋 로딩 전략 및 비동기 로딩에 대한 설명

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.