모바일에서 패키징시 액터를 제외하는 기능을 엔진팀에서 추가함

액터의 프로퍼티로 되어있고 Aactor 선언되어있음

 

그런데 실제 뷰에서 사라져야 해당 액터가 사라졌을때의 룩을 있는데 해당 기능이 없어서 구현하게됨

 

사라지는 조건은 프리뷰 피처레벨이 es3.1 이하일때

 

적용되어야 타이밍은 3

 

프리뷰 레벨이 3.1 이하인 상태에서

 

  1. 체크박스를 해제하거나 켤때
  2. 레벨을 로드할때
  3. 프리뷰 레벨을 변경할때

 

체크박스 해제시

  • 프로퍼티 변경시 호출되는 함수에서 수정

 

 

void AActor::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent)

{

    //@pts hidden Actor in Editor U_Es3_1 For ExcludeFormMobile

    if (PropertyChangedEvent.Property &&

        PropertyChangedEvent.Property->GetFName() == GET_MEMBER_NAME_CHECKED(AActor, bShouldBeExcludedFromMobile))

    {

        if (GEditor->GetActiveFeatureLevelPreviewType() >= ERHIFeatureLevel::ES3_1)

        {

            AActor::SetIsTemporarilyHiddenInEditor(bShouldBeExcludedFromMobile);

        }

    }

    //@pts hidden Actor in Editor U_Es3_1 For ExcludeFormMobile

 

 

레벨 로드시

  • 액터가 로드되는 시점에 처리

 

 

void AActor::PostLoad()

{

    Super::PostLoad();

    // add ourselves to our Owner's Children array

    if (Owner != nullptr)

    ..

..

..

        bIsSpatiallyLoaded = GridPlacement_DEPRECATED != EActorGridPlacement::AlwaysLoaded;

    }

    PRAGMA_ENABLE_DEPRECATION_WARNINGS

#endif // WITH_EDITORONLY_DATA

    // Since the actor is being loading, it finished spawning by definition when it was originally spawned, so set to true now

    bHasFinishedSpawning = true;

    //@pts hidden Actor in Editor U_Es3_1 For ExcludeFormMobile

#if WITH_EDITOR

    if (bShouldBeExcludedFromMobile)

    {

        if (UWorld* World = GetWorld())

        {

            ERHIFeatureLevel::Type FeatureLevel = World->GetFeatureLevel();

            if (FeatureLevel <= ERHIFeatureLevel::ES3_1)

            {

                AActor::SetIsTemporarilyHiddenInEditor(true);

            }

        }

    }

#endif

    //@pts hidden Actor in Editor U_Es3_1 For ExcludeFormMobile

}

 

프리뷰 레벨 변경시

프리뷰 레벨 변경시에는 액터에서 처리하기엔 너무 무리가 있어 실시간 프리뷰상태를 확인해야하는데

방법이 없음 낮은 프리퀀시의 틱으로 한다해도 모든액터가 프리뷰 레벨을 확인할 없는거고

그래서 에디터상에서 프리뷰 레벨을 변경할때 호출되는 함수나 이벤트를 찾아봄

 

 

일단 델리게이트 선언은 쉽게 찾았음 이름이 정직해서

World.h

 

DECLARE_MULTICAST_DELEGATE_OneParam(FOnActorSpawned, AActor*);

DECLARE_MULTICAST_DELEGATE_OneParam(FOnActorDestroyed, AActor*);

DECLARE_MULTICAST_DELEGATE_OneParam(FOnPostRegisterAllActorComponents, AActor*);

DECLARE_MULTICAST_DELEGATE_OneParam(FOnPreUnregisterAllActorComponents, AActor*);

DECLARE_MULTICAST_DELEGATE_OneParam(FOnActorRemovedFromWorld, AActor*);

DECLARE_MULTICAST_DELEGATE_OneParam(FOnFeatureLevelChanged, ERHIFeatureLevel::Type);

DECLARE_MULTICAST_DELEGATE_OneParam(FOnMovieSceneSequenceTick, float);

 

월드에 델리게이트_파람1 선언이 되있고 델리게이트를 받을 있게 처리만 하면되는거였는데..

 

일단 에디터모듈쪽에 등록하기로 생각하고

델리게이트 사용법을 전혀 몰라서 열심히 뒤져봄

 

FOnFeatureLevelChanged 이건 델리게이트 이름이고 뒤에 ERHIFeatureLevel::Type 이형식의 파라메터로 바인딩을 하면되는건 알겠는데 바인딩 하는방법도 모르겠어서 엔진 코드를 뒤져보니

 

FOpenColorIOEditorModule 이란 곳에서 비슷한걸 구현해둔걸 보게됨

 

 

FOnFeatureLevelChanged::FDelegate FeatureLevelChangedDelegate = FOnFeatureLevelChanged::FDelegate::CreateRaw(this, &FOpenColorIOEditorModule::OnLevelEditorFeatureLevelChanged);

    FeatureLevelChangedDelegateHandle = EditorWorld->AddOnFeatureLevelChangedHandler(FeatureLevelChangedDelegate);

 

 

이걸보니 델리게이트에 createrow add row 써서 브로드 캐스팅을 받을 함수를 등록을 하고

델리게이트를 월드의 브로드캐스팅 대상 멤버로 추가해주면 되는듯

 

아직도 약간 어렵긴하지만

결국 블루프린트의 이벤트 디스패쳐랑 비슷한 느낌으로 보면되는거같음

 

최종 함수는

 

void FTemppalEditorModule::StartupModule()

{

..

..

..

..

    FCoreDelegates::OnPostEngineInit.AddRaw(this, &FTemppalEditorModule::OnPostEngineInit);

    //@pts hidden Actor in Editor U_Es3_1 For ExcludeFormMobile

    FWorldDelegates::OnPreWorldInitialization.AddRaw(this, &FTemppalEditorModule::OnWorldInit);

    //@pts hidden Actor in Editor U_Es3_1 For ExcludeFormMobile

}

//@pts hidden Actor in Editor U_Es3_1 For ExcludeFormMobile

void FTemppalEditorModule::OnWorldInit(UWorld* InWorld, const UWorld::InitializationValues InInitializationValues)

{   if (InWorld && InWorld->WorldType == EWorldType::Editor)

    {

        WeakWorld = InWorld;

        FOnFeatureLevelChanged::FDelegate Delegate =

            FOnFeatureLevelChanged::FDelegate::CreateRaw(this, &FTemppalEditorModule::OnLevelEditorFeatureLevelChanged);

        FeatureLevelChangedDelegateHandle = WeakWorld->AddOnFeatureLevelChangedHandler(Delegate);

    }

}

void FTemppalEditorModule::OnLevelEditorFeatureLevelChanged(ERHIFeatureLevel::Type InFeatureLevel)

{

    UWorld* World = WeakWorld->GetWorld();

    if (!World) return;

    for (TActorIterator<AActor> It(World); It; ++It)

    {

        AActor* Actor = *It;

        if (Actor->bShouldBeExcludedFromMobile)

        {

            Actor->SetIsTemporarilyHiddenInEditor(InFeatureLevel <= ERHIFeatureLevel::ES3_1);

        }

    }

}

//@pts hidden Actor in Editor U_Es3_1 For ExcludeFormMobile - end

 

액터를 체크할때 뭔가 태그모음을 걸어서 태그 모음안의 액터만 처리할까도 했는데 어차피 에디터전용기능이고 모은 태그를 공유하려면 이것저것 만들어야할게 많아서 일단 여기서 마무리처리함

+ Recent posts