C++ 로 레벨 로드 및 언로드

C++ 로 만든 커스텀 스트리맹 액터가 있는 레벨 스트리밍 방법입니다.

Windows
MacOS
Linux
[INCLUDE:Basics/Levelstreaming/HowTo#levelstreamscenario]

C++ 로 레벨 스트림 인

  1. 콘텐츠 브라우저 를 열고 C++ 클래스 를 새로 만듭니다. 이 클래스는 Actor (액터) 기반이 될테니, Actor 를 선택하고 다음 을 클릭합니다.

  2. C++ 클래스 이름을 LevelStreamerActor 라 하고 클래스 생성 을 클릭합니다. 그러면 새 클래스가 Visual Studio 또는 XCode 에 보일 것입니다.

여기서는 캐릭터 가 LevelStreamerActor 의 OverlapVolume 이라는 박스 컴포넌트에 겹치면 두 번째 레벨을 스트림 인 하도록 하고 싶습니다.

  1. LevelStreamerActor.h 에서 OverlapVolume (오버랩 볼륨)을 VisibleAnywhere (아무데서나 보이고), BlueprintReadOnly (블루프린트 읽기 전용이며), AllowPrivateAccess (프라이빗 접근 허용) 메타 플래그 설정합니다.

    private:
    // 레벨 스트리밍을 발동시킬 오버랩 볼륨
    UPROPERTY(VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess = "true"))
    UBoxComponent* OverlapVolume;
  2. LevelStreamerActor.cpp 의 LevelStreamerActor 생성자에서, OverlapVolume 을 생성하고 RootComponent 로 만듭니다.

    OverlapVolume = CreateDefaultSubobject<UBoxComponent>(TEXT("OverlapVolume"));
    RootComponent = OverlapVolume;
  3. LevelStreamerActor.h 로 돌아와서 protected OverlapBegins 함수를 선언합니다. BoxComponent 의 OnComponentBeginOverlap 함수에 바인딩될 것입니다. 이 바인딩이 무슨 뜻이냐면, OverlapBegins 는 반드시 UFUNCTION 매크로로 태그되어 있어야 하며, OnComponentBeginOverlap 와 같은 시그너처를 가져야 한다는 뜻입니다.

    protected:
    
    UFUNCTION()
    void OverlapBegins(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult & SweepResult);
  4. LevelStreamerActor.h 에서, protected FName 변수를, EditAnywhere (아무데서나 편집가능)으로, LevelToLoad 라는 이름으로 생성합니다. 그러면 LevelToLoad 의 인스턴스 단위 변경이 가능해집니다.

    UPROPERTY(EditAnywhere)
    FName LevelToLoad;
  5. GameplayStatics 라이브러리의 함수를 몇 가지 사용할 것이므로, LevelStreamerActor.cpp 상단에 포함시켜 줍니다.

    #include "Kismet/GameplayStatics.h"
  6. 이제 OverlapBegins 함수 기능을 만들 준비가 되었습니다. LevelStreamerActor.cpp 에서 함수 정의를 시작합니다. GameplayStatics 함수 GetPlayerCharacter 를 사용하여 인덱스 0 의 캐릭터를 구합니다.

    void ALevelStreamerActor::OverlapBegins(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult & SweepResult)
    {
            ACharacter* MyCharacter = UGameplayStatics::GetPlayerCharacter(this, 0);        
    }
  7. MyCharacter 를 구한 뒤, BoxComponent 에 겹치는 OtherActor 에 대해 검사합니다. 또한, LevelToLoad 가 비어있지 않은지 검사한 다음, LoadStreamLevel 을 호출합니다.

    if (OtherActor == MyCharacter && LevelToLoad != "")
    {
        FLatentActionInfo LatentInfo;
        UGameplayStatics::LoadStreamLevel(this, LevelToLoad, true, true, LatentInfo);
    }
  8. LevelStreamerActor 생성자에서, OverlapBegins 를 BoxComponent 의 OnComponentBeginOverlap 에 바인딩합니다.

    OverlapVolume->OnComponentBeginOverlap.AddUniqueDynamic(this, &ALevelStreamerActor::OverlapBegins);

    최종적인 LevelStreamerActor.h 는 다음과 같습니다:

    #pragma once
    
    #include "GameFramework/Actor.h"
    #include "LevelStreamerActor.generated.h"
    
    UCLASS()
    class LEVELS_API ALevelStreamerActor : public AActor
    {
        GENERATED_BODY()
    
    public: 
        // 이 액터 프로퍼티에 대한 기본값을 설정합니다.
        ALevelStreamerActor();
    
        // 매 프레임 호출됩니다.
        virtual void Tick( float DeltaSeconds ) override;
    
    protected:
    
        // 게임 시작 또는 스폰시 호출됩니다.
        virtual void BeginPlay() override;
    
        UFUNCTION()
        void OverlapBegins(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult & SweepResult);
    
        UPROPERTY(EditAnywhere)
        FName LevelToLoad;
    
    private:
        // 레벨 스트리밍을 발동시킬 오버랩 볼륨입니다.
        UPROPERTY(VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess = "true"))
        UBoxComponent* OverlapVolume;
    
    };

    Your final LevelStreamerActor.cpp should look like:

    #include "Levels.h"
    #include "Kismet/GameplayStatics.h"
    #include "LevelStreamerActor.h"
    
    // 기본값을 설정합니다.
    ALevelStreamerActor::ALevelStreamerActor()
    {
        // 이 액터가 Tick() 을 매 프레임 호출하도록 설정합니다. 이 기능이 필요치 않은 경우 끄면 퍼포먼스가 향상됩니다.
        PrimaryActorTick.bCanEverTick = true;
    
        OverlapVolume = CreateDefaultSubobject<UBoxComponent>(TEXT("OverlapVolume"));
        RootComponent = OverlapVolume;
    
        OverlapVolume->OnComponentBeginOverlap.AddUniqueDynamic(this, &ALevelStreamerActor::OverlapBegins);
    }
    // 게임 시작 또는 스폰시 호출됩니다.
    void ALevelStreamerActor::BeginPlay()
    {
        Super::BeginPlay();
    
    }
    
    // 매 프레임 호출됩니다.
    void ALevelStreamerActor::Tick( float DeltaTime )
    {
        Super::Tick( DeltaTime );
    
    }
    
    void ALevelStreamerActor::OverlapBegins(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult & SweepResult)
    {
            ACharacter* MyCharacter = UGameplayStatics::GetPlayerCharacter(this, 0);
            if (OtherActor == MyCharacter && LevelToLoad != "")
            {
                FLatentActionInfo LatentInfo;
                UGameplayStatics::LoadStreamLevel(this, LevelToLoad, true, true, LatentInfo);
            }
    }
  9. 코드를 컴파일한 다음, 에디터로 다시 돌아옵니다.

  10. 레벨에 LevelStreamer 액터를 배치하고, 캐릭터 가 들어서면 스트리밍을 시작하도록 할 퍼시스턴트 월드의 일정 부분을 덮도록 위치와 스케일을 조절합니다. 스트리밍 레벵에서 걸어다닐 수 있는 부분도 같이 정해줍니다.

  11. Level to Stream (스트리밍할 레벨)에는 SunTemple_Streaming 이라 입력합니다.

  12. 에디터에서 플레이 기능을 사용하여 스트리밍 레벨을 테스트합니다.

C++ 로 레벨 언로드

캐릭터가 박스 컴포넌트를 빠져나갈 때 레벨을 언로드하기 위해, OverlapEnds 함수를 만들어 여기서 UGameplayStatics::UnloadStreamLevel 를 호출하여 그것을 OnComponentEndOverlap 에 바인딩합니다. LevelStreamerActor 에 다음과 같은 코드를 추가합니다:

LevelStreamerActor.h 에서:

UFUNCTION()
void OverlapEnds(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex);

LevelStreamerActor.cpp 에서:

void ALevelStreamerActor::OverlapEnds(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex)
{
        ACharacter* MyCharacter = UGameplayStatics::GetPlayerCharacter(this, 0);
        if (OtherActor == MyCharacter && LevelToLoad != "")
        {
            FLatentActionInfo LatentInfo;
            UGameplayStatics::UnloadStreamLevel(this, LevelToLoad, LatentInfo);
        }
}

생성자에서:

OverlapVolume->OnComponentEndOverlap.AddUniqueDynamic(this, &ALevelStreamerActor::OverlapEnds);
Select Skin
Light
Dark
언리얼 엔진 문서의 미래를 함께 만들어주세요! 더 나은 서비스를 제공할 수 있도록 문서 사용에 대한 피드백을 주세요.
설문조사에 참여해 주세요
건너뛰기

새로운 언리얼 엔진 4 문서 사이트에 오신 것을 환영합니다!

문서 사이트에 대한 의견을 모을 수 있는 피드백 시스템을 포함해서 여러가지 새로운 기능을 준비하고 있습니다. 아래 Documentation Feedback 포럼(영문) 또는 언리얼 엔진 네이버 공식 카페(한글) 중 편하신 곳에 의견이나 문제점을 알려 주세요.

새 시스템이 준비되면 알려 드리겠습니다.

네이버 카페
공식 포럼