[Unreal Engine C++] Fireball의 구현UnrealEngine/공부2024. 2. 27. 16:59
Table of Contents
프로젝트에서 플레이어 캐릭터의 스킬 중 하나를 파이어볼로 만들어 볼 것이다.
파이어볼은 캐릭터가 스킬 버튼을 클릭했을 시, 캐릭터의 앞에 생성된다.
이 후 앞으로 일정한 속도로 날라간 뒤 특정 액터들에 맞게 된다면 데미지를 주고 Destroy()된다.
만약 정해둔 거리 이상으로 날라가면 사라지게 만들 것이다.
파이어볼을 담당할 액터를 상속받는 TOFireball 클래스 파일을 생성한다.
//TOFireball.c
#pragma once
#include "Tellours.h"
#include "GameFramework/Actor.h"
#include "TOFireball.generated.h"
UCLASS()
class TELLOURS_API ATOFireball : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
ATOFireball();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
// 파이어볼을 담당할 컴포넌트 및 시스템
public:
UPROPERTY(VisibleAnywhere, Category = Fireball)
USphereComponent* Fireball;
UPROPERTY(VisibleAnywhere, Category = Effect)
UParticleSystemComponent* FireballEffect;
UPROPERTY(VisibleAnywhere, Category = Effect)
UParticleSystem* FireballHitEffect;
// Hit 이벤트
protected:
virtual void NotifyHit(UPrimitiveComponent* MyComp, AActor* Other, UPrimitiveComponent* OtherComp, bool bSelfMoved, FVector HitLocation, FVector HitNormal, FVector NormalImpulse, const FHitResult& Hit) override;
// 설정
private:
float SkillLength;
FVector StartVector;
};
//TOFireball.cpp
#include "TOFireball.h"
// Sets default values
ATOFireball::ATOFireball()
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
Fireball = CreateDefaultSubobject<USphereComponent>(TEXT("FIREBALL"));
FireballEffect = CreateDefaultSubobject<UParticleSystemComponent>(TEXT("EFFECT"));
FireballHitEffect = CreateDefaultSubobject<UParticleSystem>(TEXT("HITEFFECT"));
static ConstructorHelpers::FObjectFinder<UParticleSystem> FIREBALL_EFFECT(TEXT("/Game/InfinityBladeEffects/Effects/FX_Ambient/Fire/P_Lava_Splashes.P_Lava_Splashes"));
if (FIREBALL_EFFECT.Succeeded())
{
FireballEffect->SetTemplate(FIREBALL_EFFECT.Object);
FireballEffect->SetRelativeScale3D(FVector(0.25f));
FireballEffect->SetupAttachment(Fireball);
}
static ConstructorHelpers::FObjectFinder<UParticleSystem> FIREBALL_HIT_EFFECT(TEXT("/Game/Realistic_Starter_VFX_Pack_Vol2/Particles/Explosion/P_Explosion_Big_B.P_Explosion_Big_B"));
if (FIREBALL_HIT_EFFECT.Succeeded())
{
FireballHitEffect = FIREBALL_HIT_EFFECT.Object;
}
RootComponent = Fireball;
SkillLength = 600.0f;
Fireball->SetCollisionProfileName(TEXT("TOSkill"));
Fireball->CanCharacterStepUpOn = ECB_No;
}
// Called when the game starts or when spawned
void ATOFireball::BeginPlay()
{
Super::BeginPlay();
StartVector = GetActorLocation();
}
// Called every frame
void ATOFireball::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
SetActorLocation(GetActorLocation() + (GetActorForwardVector() * 600.0f * DeltaTime));
float Distance = FVector::Distance(StartVector, GetActorLocation());
if (Distance >= SkillLength)
{
Destroy();
}
}
void ATOFireball::NotifyHit(UPrimitiveComponent* MyComp, AActor* Other, UPrimitiveComponent* OtherComp, bool bSelfMoved, FVector HitLocation, FVector HitNormal, FVector NormalImpulse, const FHitResult& Hit)
{
UGameplayStatics::SpawnEmitterAtLocation(GetWorld(), FireballHitEffect, GetActorLocation(), GetActorRotation(), FVector(0.25f));
FDamageEvent DamageEvent;
Other->TakeDamage(50.0f, DamageEvent, GetWorld()->GetFirstPlayerController(), this);
Destroy();
}
코드를 설명하면 다음과 같다.
파이어볼 액터의 기본 계층구조는 RootComponent → Fireball(SphereComponent) → FireballEffect(ParticleSystemComponent)로 구성되어 있다.
스킬을 담당하는 SkillWidget에서 버튼을 클릭 시, 다음과 같은 코드가 실행된다.
FActorSpawnParameters SpawnParams;
SpawnParams.Owner = TOCharacter;
FVector FireballLocation = TOCharacter->GetActorLocation() + TOCharacter->GetActorForwardVector() * 50.0f;
GetWorld()->SpawnActor<ATOFireball>(ATOFireball::StaticClass(), FireballLocation, TOCharacter->GetActorRotation(), SpawnParams);
캐릭터의 위치에서 보는 방향 50.0f 앞에 Fireball이 생성되고, Tick이벤트로 각 틱마다 600.0f의 속도로 앞으로 이동한다.
이 때 아무것도 Hit이벤트가 생기지 않았다면, SkillLength의 거리보다 많이 이동하게 되면 Destroy()로 제거한다.
만약 Hit이벤트가 발생했으면, NotifyHit이 실행되게 된다.
NotifyHit에서는 FireballHitEffect를 생성한 뒤에, 맞은 액터에 데미지를 주고 Destroy()하게 된다.
결과는 다음과 같다.
'UnrealEngine > 공부' 카테고리의 다른 글
[Unreal Engine C++] 랜덤 맵 생성에 관한 아이디어들 (0) | 2024.03.29 |
---|---|
[Unreal Engine C++] Timeline을 사용하여 암전 효과 만들기 (0) | 2024.03.02 |
[Unreal Engine C++] 진행도에 따른 텔레포트 설정 (1) | 2024.02.27 |
[Unreal Engine C++] 현재 레벨 저장 기능의 구현 (0) | 2024.02.27 |
[Unreal Engine C++] 특정 위치로의 레벨 텔레포트의 구현 (1) | 2024.02.27 |
@NiffJB :: 개발하는 니프
CSE & GAME 개발 블로그
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 부탁드립니다!