[UE/Implement] 트랩 구현

2025. 2. 11. 23:09·Unrael/Implement

1. 개요

오늘 구현해본 트랩 기능에 대해

간단히 정리해 보았다.

 

2. 트랩 애셋 다운로드

 

spikes - Download Free 3D model by Jason_Phillips - Sketchfab

This is My Spike Model i made and animated in Maya, i used Substance Painter to Texture it

sketchfab.com

트랩 애셋은 SketchFab이라는 사이트에서 무료로 다운로드 받았다.

 

SketchFab에서 애니메이션이 포함된 애셋을 찾기 위해 아래 옵션을 활성화하여 검색했다.

  • Downloadable : 다운로드 가능한
  • Animated : 애니메이션이 포함된

 

3. 트랩 동작 생각

구현 전, 간단히 트랩이 어떻게 움직일지 전체 플로우를 생각해 보았다.

  1. 트랩은 플레이어의 오버렙을 감지한다.
  2. 감지되면 트랩 상태(Triggered)를 변경한다.
  3. 애니메이션 블루프린트에서 트랩의 상태 변경을 실시간 감지하고 애니메이션을 재생한다.

 

4. 트랩 클래스 설계

트랩 클래스는 인터페이스를 구현하도록 설계하였다.

 

1. InteractorInterface
...
class MAIN_API IInteractorInterface
{
	GENERATED_BODY()

public:
	UFUNCTION()
	virtual void OnInteractorOverlap(
		UPrimitiveComponent* OverlappedComponent,
		AActor* OtherActor,
		UPrimitiveComponent* OtherComp,
		int32 OtherBodyIndex,
		bool bFromSweep,
		const FHitResult& SweepResult) = 0;

	UFUNCTION()
	virtual void OnInteractorEndOverlap(
		UPrimitiveComponent* OverlappedComp,
		AActor* OtherActor,
		UPrimitiveComponent* OtherComp,
		int32 OtherBodyIndex) = 0;
	
	virtual void Activate(AActor* Activator) = 0;
};

 

2. BaseTrap
#pragma once

#include "CoreMinimal.h"
#include "Actors/Interface/InteractorInterface.h"
#include "GameFramework/Actor.h"
#include "BaseTrap.generated.h"

UENUM(BlueprintType)
enum ETrapState : uint8
{
	Stay,		// 이벤트 대기중
	Triggered,	// 이벤트 발생
	OnGoing,	// 이벤트 진행중
};


UCLASS(Abstract)
class MAIN_API ABaseTrap : public AActor, public IInteractorInterface
{
	GENERATED_BODY()

public:	
	ABaseTrap();

protected:
	virtual void BeginPlay() override;

/* Implement IInteractorInterface */
protected:
	UFUNCTION(BlueprintCallable)
	virtual void OnInteractorOverlap(
		UPrimitiveComponent* OverlappedComponent,
		AActor* OtherActor,
		UPrimitiveComponent* OtherComp,
		int32 OtherBodyIndex,
		bool bFromSweep,
		const FHitResult& SweepResult) override;

	UFUNCTION(BlueprintCallable)
	virtual void OnInteractorEndOverlap(
		UPrimitiveComponent* OverlappedComp,
		AActor* OtherActor,
		UPrimitiveComponent* OtherComp,
		int32 OtherBodyIndex) override;

	UFUNCTION(BlueprintCallable)
	virtual void Activate(AActor* Activator) override;

/* TrapState */
public:
	UFUNCTION(BlueprintCallable)
	ETrapState GetTrapState() const {return TrapState;}
	
	UFUNCTION(BlueprintCallable)
	void SetTrapState(ETrapState InTrapState) {TrapState = InTrapState;}
	
protected:
	ETrapState TrapState;
};
#include "Actors/Trap/BaseTrap.h"

ABaseTrap::ABaseTrap()
{
	PrimaryActorTick.bCanEverTick = false;
	TrapState = ETrapState::Stay;
}

void ABaseTrap::BeginPlay()
{
	Super::BeginPlay();
}

void ABaseTrap::OnInteractorOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor,
	UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
	if (!OtherActor || !OtherActor->ActorHasTag(TEXT("Player")))
		return;

	if (TrapState != ETrapState::Stay)
		return;
	
	TrapState = ETrapState::Triggered;
	Activate(OtherActor);
}

void ABaseTrap::OnInteractorEndOverlap(UPrimitiveComponent* OverlappedComp, AActor* OtherActor,
	UPrimitiveComponent* OtherComp, int32 OtherBodyIndex)
{
}

void ABaseTrap::Activate(AActor* Activator)
{
}

 

 3. SpikeTrap
// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "Actors/Trap/BaseTrap.h"
#include "SpikeTrap.generated.h"

/**
 * 
 */
UCLASS()
class MAIN_API ASpikeTrap : public ABaseTrap
{
	GENERATED_BODY()

public:
	ASpikeTrap();

/* ABaseTrap Implement */
protected:
	virtual void Activate(AActor* Activator) override;

/* Basic */
protected:
	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	USceneComponent* SceneComp;
	
	UPROPERTY(EditAnywhere, BlueprintReadOnly)
	USkeletalMeshComponent* SkeletalMeshComp;
};
// Fill out your copyright notice in the Description page of Project Settings.


#include "Actors/Trap/SpikeTrap.h"

ASpikeTrap::ASpikeTrap()
{
	SceneComp = CreateDefaultSubobject<USceneComponent>("SceneComp");
	SetRootComponent(SceneComp);
	
	SkeletalMeshComp = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("SkeletalMeshComp"));
	SkeletalMeshComp->SetupAttachment(SceneComp);
}

void ASpikeTrap::Activate(AActor* Activator)
{
	
}

코드 내용 정리

InteractorInterface 구현

  • InteractorInterface는 상호작용 액터들의 공통으로 호출하는 함수들을 모아놓았다.
  • InteractorInterface을 재사용하여 상호작용하는 액터들을 쉽게 구현할 수 있다. (생산성)
  • InteractorInterface로 참조하여 다른 클래스와의 느슨할 결합을 구현할 수 있다. (Solid 원칙)
  • InteractorInterface로 다양한 상호작용 액터들의 함수를 호출할 수 있다. (다형성)

 

BaseTrap 구현

  • BaseTrap은 다른 트랩 액터들의 공통으로 호출하는 함수들을 모아놓았다.
  • BaseTrap을 재사용하여 트랩 액터들을 쉽게 구현할 수 있다. (생산성)

 

SpikeTrap 구현

  • SpikeTrap은 뾰족한 가시 트랩을 상세히 구현하였다.
  • 중요한 점은 콜리전 컴포넌트를 C++상에서 추가하지 않았다.
    • 이는 블루프린트에서 트랩별 다양한 콜리전 컴포넌트를 추가할 수 있도록 구현하기 위해서다.
    • 대신 C++ 코드에서 콜리전 감지를 위해 OnInteractorOverlap를 BlueprintCallable로 설정하였다.

 

5. 트랩 블루프린트

5.1 블루프린트 생성

 

스켈레탈 메쉬와 애니메이션 블루프린트를 적용하고자 트랩 블루프린트를 생성하였다.

 

5.2 컴포넌트 구성

콜리전 컴포넌트(Box Component)를 블루프린트 단에서 추가하였다.

트랩의 특성에 따라 자유롭게 콜리전 컴포넌트르 추가할 수 있도록 구현하였다.

 

5.3 이벤트 그래프

C++ 코드에서 오버렙을 감지하고 상태를 변경할 수 있도록

콜리전 컴포넌트의 오버렙 이벤트와 C++함수를 연결하였다.

 

6. 트랩 애니메이션

6.1 애니메이션 블루프린트 생성

트랩의 상태 변경에 따라 적절한 애니메이션을 재생해주기 위하여 애니메이션 블루프린트를 생성하였다.

 

6.2  이벤트 그래프

 

간단히 살펴보면 트랩의 상태를 지속적으로 업데이트하고 있다.

 

6.3 애님 그래프

그리고 상태 스테이트 머신을 활용하여 트랩 상태에 따라 트랩이 위 아래로 움직일 수 있도록 구현하였다.

 

7. 정리

구현 전 트랩 구현이 간단하게 느껴졌지만

캐릭터와 달리 트랩 애셋의 애니메이션이 하나만 존재하여(솓구치는)

Idle애니메이션과 리셋되는 애니메이션을 언리얼 엔진에서 추가로 구현하여야 했다.

 

그리고 상태 스테이트 머신에서
역재생되는 애니메이션과 "Automatic Rule Based on Sequence Player in State" 속성이

어울려 동작하지 않는 사실을 알게 되었고 이 부분에서 애를 많이 먹었다.

 

결국 마지막에 작동하는 모습을 보고 감격에 나혼자 "Yes!"를 외쳤다.

 

'Unrael > Implement' 카테고리의 다른 글

[UE/Implement] 미니 프로젝트 회고  (0) 2025.02.13
[UE/Basic] 치트 매니저 (Cheat Manager)  (0) 2025.02.12
[UE/Implement] 액터 하이라이트 표시하기  (0) 2025.01.02
[UE/Implement] 쿼터뷰 구현하기  (0) 2024.12.31
[UE/Implement] 키 입력으로 캐릭터 움직이기  (0) 2024.12.30
'Unrael/Implement' 카테고리의 다른 글
  • [UE/Implement] 미니 프로젝트 회고
  • [UE/Basic] 치트 매니저 (Cheat Manager)
  • [UE/Implement] 액터 하이라이트 표시하기
  • [UE/Implement] 쿼터뷰 구현하기
DevColIn
DevColIn
복잡함을 단순하게
  • DevColIn
    심플한 코딩생활
    복잡함을 단순하게
  • 전체
    오늘
    어제
    • 전체보기 (223)
      • Unreal 부트캠프 (49)
        • TIL (34)
        • 사전캠프 (7)
        • 본캠프 (8)
      • Unrael (10)
        • 환경설정 (0)
        • Basic (19)
        • Component (5)
        • GAS (GameplayAbilitySystem) (3)
        • AI (2)
        • Implement (10)
        • UI (1)
        • Error (1)
        • Network (2)
        • Tip (1)
      • Level Design (5)
      • Math (1)
      • Design Pattern (16)
      • Computer Science (2)
        • Network (1)
        • Database (1)
      • Algorithm (79)
        • Basic (4)
        • Practice (74)
      • C++ (4)
        • Basic (4)
      • Tool (0)
      • Game (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 미디어로그
    • 위치로그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    Til
    본캠프
    게임동기화
    AI
    assetmanager
    액터
    Implement
    퀘스트
    unrealengine
    소프트 레퍼런신
    tsoftobjectptr
    디자인 패턴
    Animation
    unreal
    GameplayEffect
    내일배움캠프
    사전캠프
    component
    레벨디자인
    actor
    알고리즘
    basic
    Algorithm
    Design Pattern
    하드 레퍼런싱
    gas
    c++
    DesignPattern
    KPT회고
    디자인패턴
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.2
DevColIn
[UE/Implement] 트랩 구현
상단으로

티스토리툴바