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

이권용님의 프로필 이미지
이권용

작성한 질문수

이득우의 언리얼 프로그래밍 Part2 - 언리얼 게임 프레임웍의 이해

8강 아이템 시스템

boolean 변수가 변경되는 이유를 모르겠습니다.

작성

·

679

0

<#include "Item/ABItemBat.h"

#include "Components/BoxComponent.h"

#include "Components/StaticMeshComponent.h"

#include "Particles/ParticleSystemComponent.h"

#include "Physics/WMACollsion.h"

#include "Interface/ABCharacterItemInterface.h"

#include "Character/WMACharacterPlayer.h"

#include <GameData/WMAGameInstance.h>

#include "Blueprint/UserWidget.h"

#include "Components/WidgetComponent.h"

#include "UI/WMAItemInteractionWidget.h"

#include "Interface/ABCharacterItemInterface.h"

// Sets default values

AABItemBat::AABItemBat()

{

Trigger = CreateDefaultSubobject<UBoxComponent>(TEXT("TriggerBox"));

Mesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Mesh"));

Effect = CreateDefaultSubobject < UParticleSystemComponent>(TEXT("Effect"));

TextE = CreateDefaultSubobject<UWidgetComponent>(TEXT("TextE"));

Item = CreateDefaultSubobject<UABItemData>(TEXT("ItemBat"));

static ConstructorHelpers::FClassFinder<UUserWidget>InputE(TEXT("WidgetBlueprint'/Game/UI/WBP_ItemInteraction.WBP_ItemInteraction_C'"));

if (InputE.Succeeded()) {

InteractionItemWidgetClass = InputE.Class;

}

RootComponent = Trigger;

Mesh->SetupAttachment(Trigger);

Effect->SetupAttachment(Trigger);

Trigger->SetCollisionProfileName(CPROFILE_WMATRIGGER);

Trigger->SetBoxExtent(FVector(11.0f, 10.0f, 110.0f));

Trigger->OnComponentBeginOverlap.AddDynamic(this, &AABItemBat::OnOverlapBegin);

Trigger->OnComponentEndOverlap.AddDynamic(this,&AABItemBat::OnOverlapEnd);

static ConstructorHelpers::FObjectFinder<UStaticMesh> BoxMeshRef(TEXT("/Script/Engine.StaticMesh'/Game/Item/Bat/Batfbx.Batfbx'"));

if (BoxMeshRef.Succeeded()) {

TempBoxMesh = BoxMeshRef.Object;

Mesh->SetStaticMesh(BoxMeshRef.Object);

}

Mesh->SetRelativeLocation(FVector(0.0f, -3.5f, -20.0f));

Mesh->SetCollisionProfileName(TEXT("NoCollision"));

bInteractionItem = false;

PrimaryActorTick.bCanEverTick = true;

}

void AABItemBat::Tick(float DeltaTime)

{

Super::Tick(DeltaTime);

//UE_LOG(LogTemp, Warning, TEXT("Character is Die :: %s"), bInteractionItem ? TEXT("true") : TEXT("false"));

if (bInteractionItem) {

Trigger->OnComponentBeginOverlap.AddDynamic(this, &AABItemBat::OnOverlapBegin);

UE_LOG(LogTemp,Warning,TEXT("NO item Attach"))

}

}

void AABItemBat::OnOverlapBegin(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepHitResult)

{

//TextE->SetHiddenInGame(false);

if (InteractionItemWidgetClass) {

ItemText = CreateWidget<UUserWidget>(GetWorld(), InteractionItemWidgetClass);

if(ItemText)

ItemText->AddToViewport();

}

if (nullptr == Item) {

Destroy();

return;

}

//UE_LOG(LogTemp, Warning, TEXT("Character is Die :: %s"), bInteractionItem ? TEXT("true") : TEXT("false"));

if (bInteractionItem) {

IABCharacterItemInterface* OverlappingPawn = Cast<IABCharacterItemInterface>(OtherActor);

if (OverlappingPawn) {

OverlappingPawn->TakeItem(Item);

//TextE->SetHiddenInGame(true);

}

//Effect->Activate(true);

Mesh->SetHiddenInGame(true);

SetActorEnableCollision(false);

Effect->OnSystemFinished.AddDynamic(this, &AABItemBat::OnEffectFinished);

Trigger->OnComponentBeginOverlap.RemoveDynamic(this, &AABItemBat::OnOverlapBegin);

}

}

void AABItemBat::OnOverlapEnd(UPrimitiveComponent* OverlappedComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex)

{

if (ItemText) {

ItemText->RemoveFromViewport();

ItemText = nullptr;

}

}

void AABItemBat::OnEffectFinished(UParticleSystemComponent* ParticleSystem)

{

Destroy();

}

void AABItemBat::StartInteractionItem()

{

bInteractionItem = true;

}

void AABItemBat::StopInteractionItem()

{

//bInteractionItem = false;

}>

 

일단 WMACharacterplayer.cpp에서 StartInteractionItem()을 호출하는데는 문제가 없습니다.

StartInteractionItem() 함수 내부에서 로그를 출력해보면 bInteractionItem이 true로 잘 출력이 되는 것을 확인할 수 있습니다.

 

문제는 Tick함수 내부와 OnOverlapBegin()함수 내부에서 로그를 찍어보면 bInteractionItem이 false로 변경되어서 OnOverlapBegin()함수를 호출하지 못하고 있는 상황입니다.

 

혹시 어느 부분이 문제가 되어 bool값이 변경되는지 여쭐수 있을까요?

답변 1

0

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

음.. 코드를 보면 제가 만든 예제 코드는 아닌것 같은데,
우선 Tick에서 델리게이트를 등록하는 코드는 안 좋은 방법입니다.
Trigger->OnComponentBeginOverlap.AddDynamic(this, &AABItemBat::OnOverlapBegin);
원하시는 기능이 어떤 것인지 정확히 모르겠지만, 다른 형태로 해결 방법을 고민하셔야 할 것 같아요.
기본적인 액터의 구성 요소의 초기화는 델리게이트 지정은 생성자나 PostInitializeComponents 함수에서 해주시고, OnOverlapBegin 같은 이벤트 함수에서는 상태 값만 변경하도록 지정해주시는게 좋습니다.
AddDynamic을 두 번 이상 호출한다면 Remove를 명확하게 맞춰 델리게이트가 객체에 하나만 연동되게끔 잘 정리해주시고요, Tick함수는 사용자 입력 처리와 같이 매 프레임마다 점검하는 용도가 아니라면 가급적 사용하지 않는게 좋습니다.
하나의 함수에서 if 문으로 여러 분기를 만들어 직접 처리하기보다 상태 값을 변경하고, 상태의 변경을 감지해 자연스럽게 처리하는 함수를 호출하도록 구조를 한번 고민해보세요.
한 번 다시 정리해보시면서 디버깅을 활용하면 원하시는 답을 찾을 수 있지 않을까 생각합니다.

이권용님의 프로필 이미지
이권용

작성한 질문수

질문하기