0. 개요
드랍된 아이템이 제자리 회전을 하며 상하로 사인파 운동을 하게 한다.
1. 효과 액터
물약, 크리스탈과 같이 캐릭터와 접촉하면 효과를 일으키는 AuraEffectActor를 대상으로 여러 이펙트를 추가한다.
(1) AuraEffectActor의 틱 활성화
(1-1) Tick 함수 오버라이드
protected:
virtual void BeginPlay() override;
virtual void Tick(float DeltaTime) override;
(1-2) 생성자에서 틱 활성화
AAuraEffectActor::AAuraEffectActor()
{
PrimaryActorTick.bCanEverTick = true;
(2) 상하 사인파 운동과 회전 운동 관련 멤버 변수와 함수 추가
protected:
/*
* Movement Effect
*/
UPROPERTY(BlueprintReadOnly)
FVector CalculatedLocation;
UPROPERTY(BlueprintReadOnly)
FRotator CalculatedRotation;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Pickup Movement")
bool bRotates = true;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Pickup Movement")
float RotationRate = 45.f;
// 상하 사인파 움직임
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Pickup Movement")
bool bSinusoidalMovement = false;
// 진폭
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Pickup Movement")
float SinAmplitude = 1.f;
// 주기
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Pickup Movement")
float SinPeriodConstant = 1.f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Pickup Movement")
FVector InitialLocation;
UFUNCTION(BlueprintCallable)
void StartSinusoidalMovement();
UFUNCTION(BlueprintCallable)
void StartRotation();
(2-1) 상하 사인파 운동
- bSinusoidalMovement 불리언 : 상하 사인파 운동을 할지 결정하는 불리언
- SinAmplitude : 사인파 진폭
- SinPeriodConstant : 파수, 기본 2pi의 값을 파수로 나눠 주기를 상하 운동을 빠르게 혹은 느리게 한다
- InitialLocation : 초기 액터의 위치
- StartSinusoidalMovement : 기본 값을 대입하고 사인파 운동을 준비
private:
// 사인파 움직임 시간
float RunningTime = 0.f;
void ItemMovement(float DeltaTime);
- RunningTime : 사인파를 따라 움직이고 있는 시간
- ItemMovement : 사인파 운동과 회전 운동을 실시
(2-2) 회전 운동
- bRotates 불리언 : 제자리 회전 운동을 할지 결정하는 불리언
- RotationRate : 초당 회전 각
- StartRotation : 기본 값을 대입하고 제자리 회전 운동을 준비
(2-3) 프록시 값
AuraEffectActor의 메시는 블루프린트에서 지정하고 있기 때문에, Set Actor Location 혹은 Set Actor Rotation을 블루프린트에서 호출할 것이다.
따라서, 위치와 회전 계산 값을 C++ 코드로 계산하여 들고 있는다.
(3) 사전 설정
void AAuraEffectActor::BeginPlay()
{
Super::BeginPlay();
InitialLocation = GetActorLocation();
}
void AAuraEffectActor::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
RunningTime += DeltaTime;
const float SinPeriod = 2 * PI / SinPeriodConstant;
// 사인파 진행 시간이 주기를 넘으면 초기화
if (RunningTime > SinPeriod)
RunningTime = 0.f;
ItemMovement(DeltaTime);
}
BeginPlay에서는 초기 위치를 구한다.
Tick에서는 사인 주기를 계산하고 진행 시간이 주기를 넘으면 다시 0부터 시작하도록 초기화한다.
(4) 회전파 운동, 회전 운동 시작 함수
void AAuraEffectActor::StartSinusoidalMovement()
{
bSinusoidalMovement = true;
InitialLocation = GetActorLocation();
CalculatedLocation = InitialLocation;
CalculatedRotation = GetActorRotation();
}
void AAuraEffectActor::StartRotation()
{
bRotates = true;
CalculatedRotation = GetActorRotation();
CalculatedLocation = InitialLocation;
}
각 초기값과 결과값을 미리 세팅한다.
(5) 운동 함수
void AAuraEffectActor::ItemMovement(float DeltaTime)
{
// 회전
if (bRotates)
{
const FRotator DeltaRotation(0.f, DeltaTime * RotationRate, 0.f);
// 쿼터니언으로 변경 후 더하기
CalculatedRotation = UKismetMathLibrary::ComposeRotators(CalculatedRotation, DeltaRotation);
}
// 사인파 움직임
if (bSinusoidalMovement)
{
const float Sine = SinAmplitude * FMath::Sin(RunningTime * SinPeriodConstant);
CalculatedLocation = InitialLocation + FVector(0.f, 0.f, Sine);
}
}
회전은 축 겹침 문제를 회피하기 위해 ComposeRotators 함수를 사용한다.
이 함수는 두 FRotator를 쿼터니언으로 변환하여 더하고 반환한다.
2. 픽업 아이템의 부모 BP_Pickup_Base
이 프로젝트의 물약과 크리스탈은 AuraEffectActor를 상속받아 각각 메시를 적용하고 있다.
이제 운동이 도입되면서 물약과 크리스탈을 블루프린트로 래핑할 필요가 있어졌다.
(1) AuraEffectActor를 상속받는 BP_Pickup_Base 생성
위에서 계산한 값을 이용해 액터의 위치와 회전을 계산한다.
(2) 포션과 크리스탈의 부모 클래스 변경, 클래스 디폴트 수정
클래스 세팅에서 부모를 위의 블루프린트로 변경한다.
클래스 디폴트에서 각속도와 진폭, 파수를 결정한다.
'UE 5 스터디 > Gameplay Ability System(GAS)' 카테고리의 다른 글
30-13. 아이템 - (4) 획득 사운드 (0) | 2025.04.17 |
---|---|
30-12. 아이템 - (3) 드랍 아이템 효과 (0) | 2025.04.17 |
30-10. 아이템 - (1) 아이템 드랍 (0) | 2025.04.16 |
30-9. 레벨 디자인 - (2) 플레이어 사망 (0) | 2025.04.16 |
30-8. 레벨 디자인 - (1) 몬스터 소환 볼륨 (0) | 2025.04.15 |