[Unreal_C++_DarkSoul]#19_Portal
서로 다른 Level을 오가는 Portal을 구현합니다.
Overview
- 개요 및 설계
- 코드
- 영상
#0. 개요 및 설계
1. 목적
- 플레이어가 서로 다른 레벨을 오갈 수 있는 Portal을 구현합니다.
2. 설계
- Player 객체는 특정 키 입력과 동시에 Portal 객체와의 충돌 여부를 체크하고 델리게이트 함수를 실행합니다.
- Portal 객체는 Player 객체가 선언한 델리게이트 함수를 Level Change 함수와 동적 바인딩을 수행하고, 미리 설정한 다음 Level을 열어줍니다.
#1. 코드
1. PlayerCharacter 클래스
//...
void APlayerCharacter::OnChangeLevel()
{
TArray<AActor*> OverlappingActors;
GetOverlappingActors(OverlappingActors, APortal::StaticClass());
for (const auto OverlappingActor : OverlappingActors)
{
APortal* Portal = Cast<APortal>(OverlappingActor);
if (!!OverlappingActor && !!Portal)
{
OnSwitchLevel.Broadcast(this);
}
}
}
Details
- PlayerCharacter 클래스에서 선언한 OnChangeLevel은 키보드의 "x"키와 바인딩되어, Portal 객체와의 충돌 여부 체크와 OnSwitchLevel 델리게이트 함수를 실행합니다.
2. Portal 클래스
#include "Portal.h"
#include "Global/Global.h"
#include "Components/SphereComponent.h"
#include "NiagaraComponent.h"
#include "GameObjects/PlayerCharacter.h"
#include "ActorComponents/C_WeaponComponent.h"
#include "Engine/LevelStreaming.h"
APortal::APortal()
{
PrimaryActorTick.bCanEverTick = false;
Sphere = CreateDefaultSubobject<USphereComponent>(TEXT("Sphere"));
PortalEffect = CreateDefaultSubobject<UNiagaraComponent>(TEXT("Portal Effect"));
SetRootComponent(Sphere);
Sphere->InitSphereRadius(350.f);
Sphere->SetVisibility(true);
Sphere->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics);
PortalEffect->SetupAttachment(Sphere);
PortalEffect->bAutoActivate = true;
}
void APortal::BeginPlay()
{
Super::BeginPlay();
APlayerController* PlayerController = GetWorld()->GetFirstPlayerController();
APlayerCharacter* PlayerCharacter = Cast<APlayerCharacter>(PlayerController->GetPawn());
if (!!PlayerController && !!PlayerCharacter)
{
PlayerCharacter->OnSwitchLevel.AddDynamic(this, &APortal::SwitchLevel);
}
}
// [23-07-07] Level Change
void APortal::SwitchLevel(AActor* InActor)
{
ULevel* CurrentLevel = GetWorld()->GetCurrentLevel();
if (!!CurrentLevel)
{
// #1. State 저장
if (!!InActor)
{
HandOverObjectCurrentState(&InActor);
}
// #2. New Level 열기
FString CurrentLevelPath = GetWorld()->GetCurrentLevel()->GetOutermost()->GetName();
FString CurrentLevelName = FPaths::GetCleanFilename(CurrentLevelPath).RightChop(9);
if (!CurrentLevelName.IsEmpty())
{
if (!NextLevelName.IsEmpty())
{
UGameplayStatics::OpenLevel(GetWorld(), FName(NextLevelName));
}
else
{
PrintLine();
return;
}
}
}
}
void APortal::HandOverObjectCurrentState(AActor** InActor)
{
if (!!(*InActor))
{
UC_WeaponComponent* WeaponComp = (*InActor)->FindComponentByClass<UC_WeaponComponent>();
if (!!WeaponComp)
{
TArray<AWeapon*> Weapons = WeaponComp->GetWeapons();
OnLevelChanged.ExecuteIfBound(Weapons);
}
}
}
Details
- Portal 클래스는 Sphere Component를 갖습니다. Sphere Component의 지름을 350.f로 설정해 Player 객체가 Portal 객체와 충돌했음을 알려주기 위해 선언했습니다.
- Portal 클래스는 PlayerCharacter 객체가 선언한 OnSwitchLevel 델리게이트 함수에 ChangeLevel 함수를 동적 바인딩합니다.
- SwitchLevel 함수는 Portal 객체와 충돌한 Player 객체의 Level 전환을 수행합니다. Switch Level 함수는 호출 시 NextLevelName을 갖는 Map을 찾아서 열어줍니다.
#2. 영상
'개인프로젝트' 카테고리의 다른 글
[Unreal_C++_DarkSoul]#21_기능 구현, 데이터 변환 (0) | 2023.11.05 |
---|---|
[Unreal_C++_DarkSoul]#20_기능 구현, Level Sequence (0) | 2023.09.17 |
[Unreal_C++_DarkSoul]#18_기능 구현, Sound (0) | 2023.07.23 |
[Unreal_C++_DarkSoul]#17_기능 구현, Grid 클래스 (0) | 2023.06.03 |
[Unreal_C++_DarkSoul]#16_문제 해결, 런 타임 AI 실행 여부 (0) | 2023.05.27 |