작성
·
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 인턴입니다.
언리얼 엔진에서 애셋을 로딩할 때, 생성자 단계와 Init 함수에서의 로딩 방식의 차이점은 주로 엔진의 초기화 상태와 관련이 있습니다.
생성자에서는 아직 엔진의 모든 서브시스템이 초기화되기 전 단계이기 때문에, LoadObject<>()
와 같은 런타임 로딩 API를 사용하는데 제한이 있습니다. 이는 생성자에서 직접적인 리소스 접근은 엔진 상태와 관계없이 로드되기 때문에 활성화되어 있는 모든 관련 시스템 또는 콘텐츠가 준비되지 않은 상태에서 로드를 시도할 수 있어 문제가 발생할 수 있다는 점에서 비롯됩니다.
반면, Init 함수는 엔진이 충분히 초기화된 후 호출됩니다. 이 시점에는 모든 서브시스템이 정상적으로 준비되어 있으므로 런타임 로딩 API를 안전하게 사용할 수 있습니다. 이 때문에 LoadStudentObject()
에서는 LoadObject<>()
를 통해 애셋을 로드하는 것이 가능합니다. 이 경우, 엔진이 필요한 종속성을 모두 충족시킨 환경에서 안전하게 로딩이 가능합니다.
LoadObject()
함수는 지정한 경로에 해당하는 애셋이 존재하지 않을 경우, nullptr
을 반환하게 됩니다. 일반적으로 로딩 이후에 포인터에 대한 nullptr
체크를 수행하여 성공 여부를 확인하는 것이 좋습니다. 하지만 특정 상황에서는 이미 애셋이 존재한다고 확신할 수 있어 체크를 생략하는 경우도 있습니다. 이는 기본적으로 애셋 경로의 유효성이 선행되어 보장되며, 경로가 잘못되거나 애셋이 존재하지 않는 경우에는 Null Pointer 예외가 발생할 수 있으니 주의해야 합니다.
다음 링크를 통해 더 많은 정보와 예제를 확인하실 수 있습니다:
- 에셋 로딩 전략 및 비동기 로딩에 대한 설명
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.