지난 포스팅에서 만든 지오메트리 컬렉션은 헤일로 클래스에 넣을 것이다.
평상시에는 지오메트리 컬렉션이 스태틱 메시의 역할을 해주다가, 칸나의 체력이 0이 되면 메시를 깨뜨릴 것이다.
Halo.h:
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Halo.generated.h"
class UGeometryCollectionComponent;
UCLASS()
class KANNATPS_API AHalo : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
AHalo();
// Called every frame
virtual void Tick(float DeltaTime) override;
UFUNCTION(BlueprintNativeEvent)
void BreakHalo();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
private:
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
UGeometryCollectionComponent* GeometryCollection;
UPROPERTY()
ACharacter* KannaCharacter;
FVector TargetLocation;
FRotator TargetRotation;
};
UGeometryCollectionComponent* GeometryCollection이 그것이다.
BreakHalo가 BlueprintNativeEvent로 되어있는데, C++와 블루프린트 양쪽에서 기능을 구현하기 위해서이다.
Halo.cpp:
// Fill out your copyright notice in the Description page of Project Settings.
#include "Objects/Halo.h"
#include "GeometryCollection/GeometryCollectionComponent.h"
#include "Kismet/GameplayStatics.h"
#include "Components/SkeletalMeshComponent.h"
#include "GameFramework/Character.h"
// Sets default values
AHalo::AHalo()
{
// 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;
GeometryCollection = CreateDefaultSubobject<UGeometryCollectionComponent>(TEXT("GeometryCollection"));
GeometryCollection->SetupAttachment(GetRootComponent());
}
// Called when the game starts or when spawned
void AHalo::BeginPlay()
{
Super::BeginPlay();
KannaCharacter = UGameplayStatics::GetPlayerCharacter(GetWorld(), 0);
TargetLocation = KannaCharacter->GetMesh()->GetSocketLocation(FName("Halo_Socket"));
TargetRotation = KannaCharacter->GetMesh()->GetSocketRotation(FName("Halo_Socket"));
SetActorLocationAndRotation(TargetLocation, TargetRotation);
}
void AHalo::BreakHalo_Implementation()
{
GeometryCollection->SetSimulatePhysics(true);
GeometryCollection->SetEnableGravity(true);
}
// Called every frame
void AHalo::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
TargetLocation = KannaCharacter->GetMesh()->GetSocketLocation(FName("Halo_Socket"));
TargetRotation = KannaCharacter->GetMesh()->GetSocketRotation(FName("Halo_Socket"));
SetActorLocation(FMath::VInterpTo(GetActorLocation(), TargetLocation, DeltaTime, 12.5f));
SetActorRotation(FMath::RInterpTo(GetActorRotation(), TargetRotation, DeltaTime, 12.5f));
}
BreakHalo 호출 시 C++에서는 Simulate Physics, Gravity를 활성화해준다. (기본값은 꺼져있도록 함)
저 두 가지가 모두 켜져있어야 파괴 연출이 가능했다.
에디터에서 Geometry Collection에 지난 포스팅에서 만든 에셋을 넣어주었다.
디테일 패널의 Damage Threshold는 얼마만큼의 충격을 받아야 메시가 깨질 지를 나타내는데, 사망 순간에만 스크립트로 힘을 가해줄 것이기 때문에 굳이 높을 이유가 없어 1로 해두었다.
이전 이미지에서 보이다시피, CullingField, RadialVector, RadialFalloff 컴포넌트는 미리 만들어두었다. (모두 기본 세팅)
BreakHalo의 구현:
- SetRadialFalloff로 힘을 가할 구형 공간을 만들어준다. 헤일로에만 작용할 정도의 범위면 되므로 클 필요는 없다.
- RadialVector를 준비해준다. Field Magnitude는 헤일로가 깨지는 힘을 나타낸다.
- SetCullingField에 1번에서 만든 필드를 CullingField로, 2번에서 만든 필드를 InputField로 넣어준다.
- CullingField를 이용해서 RadialVector가 RadialFalloff 내에서만 작용하도록 만든 것이다.
- CullingOperation을 Outside로 함은 곧 필드 바깥을 컬링, 즉 제외하겠다는 것이다.
- Add Transient Field 노드를 통해 1번에서 만든 필드를 활성화시켜준다.
- Physics Type의 각 종류에 대한 설명은 https://docs.unrealengine.com/5.0/ko/reference-guide-for-physics-field-in-unreal-engine/
- 또 다른 Add Transient Field 노드를 통해 3번에서 만든 필드도 활성화시켜준다.
- Play Sound 2D노드를 통해 깨지는 소리를 재생한다.
다음 포스팅에서는 이 로직이 HP가 0이 되면 호출되도록하고, 사망 시 화면 연출을 만드는 과정을 담을 것이다.
'언리얼 엔진 5 > 개발 일지' 카테고리의 다른 글
[UE5] 블루아카이브 TPS게임 개발일지 (60) - GameManager로 적 관리 (0) | 2024.02.17 |
---|---|
[UE5] 블루아카이브 TPS게임 개발일지 (59) - 사망 연출 제작 3 (0) | 2024.02.16 |
[UE5] 블루아카이브 TPS게임 개발일지 (57) - 사망 연출 제작 (Geometry Collection) (0) | 2024.02.16 |
[UE5] 블루아카이브 TPS게임 개발일지 (56) - EX 스킬 제작 4 (0) | 2024.02.04 |
[UE5] 블루아카이브 TPS게임 개발일지 (55) - EX 스킬 제작 3 (UParticleSystem) (0) | 2024.02.02 |