NPC에 상호작용이 가능하게 할수있는 콜리전을 달아줍니다
사용할 헤더추가
#include "Components/SphereComponent.h"
트리거용 스피어컴포넌트와 탐지될 범위를 지정해줍니다
UPROPERTY(EditAnywhere)
class USphereComponent* detectSphere;
UPROPERTY(EditAnywhere, Category="Detect")
float detectRadius = 200.0;
플레이어한테 붙혀주고 범위를 설정해줍니다
detectSphere = CreateDefaultSubobject<USphereComponent>(TEXT("detectSphere"));
detectSphere->SetupAttachment(RootComponent);
detectSphere->SetSphereRadius(detectRadius);
detectSphere->SetCollisionProfileName(TEXT("npcInterectionTrigget"));
위젯 컴포넌트를 달아줍니다
#include "Components/WidgetInteractionComponent.h"
UPROPERTY(EditAnywhere, Category = "Detect")
class UWidgetInteractionComponent* npcGWidgetInteractionComponent;
npcGWidgetInteractionComponent = CreateDefaultSubobject<UWidgetComponent>(TEXT("GInteractionComponent"));
npcGWidgetInteractionComponent->SetupAttachment(RootComponent);
npcGWidgetInteractionComponent->SetRelativeLocation(FVector(52.f, 0.f, 52.f));
npcGWidgetInteractionComponent->SetWidgetSpace(EWidgetSpace::Screen);
npcGWidgetInteractionComponent->SetVisibility(false);
사용할 위젯을 만들어주고 InteractionComponent에 넣어줍니다
Beginoverlap과 Endoverlap을 처리해줍니다
void ANpcUits::BeginPlay()
{
Super::BeginPlay();
detectSphere->OnComponentBeginOverlap.AddDynamic(this, &ANpcUits::OnBeginOverlapNpc);
detectSphere->OnComponentEndOverlap.AddDynamic(this, &ANpcUits::EndOverlapNpc);
}
BeginOverlap은 PrimitiveComponent의
UPrimitiveComponent* OverlappedComponent 부터 const FHitResult & SweepResult까지 입니다
UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult
EndOverlap은 PrimitiveComponent의
UPrimitiveComponent* OverlappedComponent 부터 Int32 OtherBodyIndex 까지 입니다
UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex
플레이어를 선언후 플레이어가 오버랩 / 엔드오버랩 이벤트가 발생하면 g 인터렉선 위젯이 보이게 / 안보이게 설정해줍니다
class ASwordCharacter* player;
void ANpcUits::OnBeginOverlapNpc(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
player = Cast<ASwordCharacter>(UGameplayStatics::GetPlayerCharacter(GetWorld(), 0));
if (OtherActor == player)
{
npcGWidgetInteractionComponent->SetVisibility(true);
}
}
void ANpcUits::EndOverlapNpc(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex)
{
if (OtherActor == player)
{
npcGWidgetInteractionComponent->SetVisibility(false);
}
}
상호작용할 npc를 구분해주는 코드를 추가해줍니다
캐릭터에서 상호작용할 npc를 선언
UPROPERTY()
ANpcUits* currentInteractionNpc = nullptr;
오버랩 되었을때 포인터를 this로 넘겨줍니다
void ANpcUits::OnBeginOverlapNpc(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
player = Cast<ASwordCharacter>(UGameplayStatics::GetPlayerCharacter(GetWorld(), 0));
if (OtherActor == player)
{
player->currentInteractionNpc = this;
}
}
상호작용하면 시점이 바뀔 시네 카메라를 세팅해줍니다
사용할 헤더 추가
#include "CineCameraActor.h"
#include "EngineUtils.h"
포인터를 저장할 CineCameraActor인 npcInteractionCamera와
무슨카메라인지를 구분하기위한 Name타입 npcCameraTagName를 선언
UPROPERTY()
ACineCameraActor* npcInteractionCamera;
UPROPERTY(EditAnywhere, Category = "Sequence")
FName npcCameraTagName;
BeginPlay에서 iterator로 이름이 npcCamera로 설정된걸 찾아 npcInteractionCamera포인터에 저장해줍니다
태그로 설정한 카메라만 찾게됩니다
각각 태그를 달아줍니다
--장비판매npc--
--물약npc--
각각 달린 태그이름이 가진 카메라를 npcInteractionCamera포인터에 저장하게됩니다
void ANpcUits::BeginPlay()
{
Super::BeginPlay();
for (TActorIterator<ACineCameraActor>it(GetWorld()); it; ++it)
{
ACineCameraActor* npcOwnCamera = *it;
if (npcOwnCamera->GetName() == npcCamera)
{
npcInteractionCamera = npcOwnCamera;
}
}
}
사용하고있는 컨트롤러가 npcInteractionCamera로 시점이 변경되며
플레이어메시,모든하이어라키 자식들과 InteractionHidePlayerWidget함수로 현재 사용하고있는 위젯을 잠시 숨깁니다
InteractionHidePlayerWidget함수는 지금 플레이어가 사용하고있는 위젯을 숨기는 커스텀함수입니다
void ANpcUits::StartInteractionCamera()
{
player = Cast<ASwordCharacter>(UGameplayStatics::GetPlayerCharacter(GetWorld(), 0));
player->GetMesh()->SetVisibility(false, true);
APlayerController* pc = Cast<APlayerController>(player->GetController());
ASwordPlayController* swordCon = Cast<ASwordPlayController>(pc);
if (player)
{
swordCon->SetViewTargetWithBlend(npcInteractionCamera, 1.0f);
swordCon->InteractionHidePlayerWidget();
}
}
Interaction 대화창을 만들어줍니다
위젯에서 npcText매개변수값으로 텍스트를 변경합니다
void UNpcInteractionWidget::SetInteractionText(FString& npcText)
{
TextBlock_Interaction->SetText(FText::FromString(npcText));
}
npc에 할당되어있는 npcInteractionTalk string값으로 변경이됩니다
UPROPERTY(EditAnywhere, Category = "Interaction")
FString npcInteractionTalk;
interactionWidgetInstance->SetInteractionText(npcInteractionTalk);
상호작용할때 npc가 행동하는 애니메이션을 mixamo에서 들고오겠습니다
들고올 애니메이션입니다
해당 애니메이션을 리타게팅하여 위젯이 보여질때 플레이되도록 했습니다
또한 npc머리위에 네임플레이트를 달아주었습니다
UPROPERTY(EditAnywhere, Category = "Interaction")
UWidgetComponent* NamePlateWidget;
NamePlateWidget = CreateDefaultSubobject<UWidgetComponent>(TEXT("NamePlate"));
NamePlateWidget->SetupAttachment(RootComponent);
NamePlateWidget->SetWidgetSpace(EWidgetSpace::Screen);
NamePlateWidget->SetRelativeLocation(FVector(0.f, 0.f, 130.f));
결과물
'Unreal5 프로젝트 다이어리' 카테고리의 다른 글
Unreal - Look At (고개 돌리기) (1) | 2025.06.28 |
---|---|
Unreal - 컷씬 리터칭 (0) | 2025.06.27 |
Unreal - 비동기 로딩 Level Streaming (0) | 2025.06.26 |
Unreal - LandScape 발소리 (0) | 2025.06.26 |
Unreal - BGM, 사운드 관리법 (0) | 2025.06.21 |