[언리얼엔진] 2. VR 버튼 구현

2026. 4. 4. 18:22·Unreal Engine 프로젝트/VR 공포게임

결과물

빠른 속도로 눌러야만 인식되는 버튼을 구현했습니다.

 


 

구현 내용

1. ISequenceable.h / .cpp

ActorSequence라는 기능을 활용해서 버튼을 눌렀을 때 눌리는 연출을 출력하려고 합니다. 하지만, 현재 ActorSequence는 Experimental 기능이기 때문에 C++에서 컴포넌트로 추가했을 때 블루프린트 에디터에서 Sequence 탭이 보이지 않는 버그가 존재합니다. 따라서, ActorSequence는 블루프린트 에디터 상에서 추가하고, 재생 기능은 C++로 관리합니다.
Sequence의 시작과 끝 이벤트에 함수를 바인딩하도록 해서 추후 이벤트 설계에 용이하게 진행하려고 합니다.

ISequenceable.h

더보기
#pragma once

#include "CoreMinimal.h"
#include "UObject/Interface.h"
#include "Sequenceable.generated.h"

UINTERFACE(NotBlueprintable)
class USequenceable : public UInterface
{
	GENERATED_BODY()
};

class VIRTUALREALITY_API ISequenceable
{
	GENERATED_BODY()
	
public:
	UFUNCTION()
	virtual void OnSequenceStarted() = 0;
	
	UFUNCTION()
	virtual void OnSequenceEnded() = 0;
	
protected:
	void PlaySequence();
	
private:
	uint8 bIsBound : 1 = false;
	
};

ISequenceable.cpp

더보기
#include "Sequenceable.h"
#include "ActorSequenceComponent.h"
#include "ActorSequencePlayer.h"
#include "VirtualReality.h"

void ISequenceable::PlaySequence()
{
	AActor* Owner = Cast<AActor>(this);
	if (!Owner)
	{
		LOG(TEXT("Sequenceable는 AActor에만 적용 가능합니다. 함수를 종료합니다."));	
		return;
	}
	
	UActorSequenceComponent* SeqComp = Owner->FindComponentByClass<UActorSequenceComponent>();
	if (!SeqComp)
	{
		LOG(TEXT("ActorSequence가 존재하지 않습니다."));
		return;
	}

	UActorSequencePlayer* Player = SeqComp->GetSequencePlayer();
	if (!Player) return;
	
	if (!bIsBound)
	{
		Player->OnPlay.AddDynamic(this, &ThisClass::OnSequenceStarted);
		Player->OnFinished.AddDynamic(this, &ThisClass::OnSequenceEnded);
		bIsBound = true;
	}
	
	Player->Play();
}

 


 

2. ATriggerableActor.h / .cpp

이번엔 Collision에 닿았을 때 이벤트가 발생하는 오브젝트를 구현하고자 합니다. 해당 오브젝트들의 베이스 클래스를 구현해주었습니다. 자식들은 OnTriggered 함수를 오버라이딩 함으로써 간단하게 Trigger 이벤트를 구현할 수 있습니다. 현재는 테스트 용으로 VRHand가 Z축으로 닿는 속도가 300이상일 때에만 이벤트가 트리거 되도록 구현했습니다.

ATriggerableActor.h

더보기
#pragma once

#include "CoreMinimal.h"
#include "Actor/VRActorBase.h"
#include "TriggerableActor.generated.h"

class UBoxComponent;

UCLASS()
class VIRTUALREALITY_API ATriggerableActor : public AVRActorBase
{
	GENERATED_BODY()
	
public:
	ATriggerableActor();
	virtual void BeginPlay() override;

protected:
	virtual void OnTriggered();
	
private:
	UFUNCTION()
	void OnOverlapBegin(UPrimitiveComponent* OverlappedComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult);
	
protected:
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "변수|컴포넌트")
	TObjectPtr<UBoxComponent> TriggerRegion;

};

ATriggerableActor.cpp

더보기
#include "TriggerableActor.h"
#include "VirtualReality.h"
#include "Components/BoxComponent.h"
#include "Player/VRHand.h"


ATriggerableActor::ATriggerableActor()
{
	TriggerRegion = CreateDefaultSubobject<UBoxComponent>(TEXT("TriggerRegion"));
	TriggerRegion->SetupAttachment(Mesh);
}

void ATriggerableActor::BeginPlay()
{
	Super::BeginPlay();
	
	TriggerRegion->OnComponentBeginOverlap.AddDynamic(this, &ATriggerableActor::OnOverlapBegin);
}

void ATriggerableActor::OnTriggered()
{
}

void ATriggerableActor::OnOverlapBegin(UPrimitiveComponent* OverlappedComp, AActor* OtherActor,
                                       UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
	if (!OtherActor || OtherActor == this) return;
	
	if (AVRHand* Hand = Cast<AVRHand>(OtherActor))
	{
		if (FMath::Abs(Hand->GetHandVelocity().Z) >= 300.0f)
		{
			GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Yellow, FString::Printf(TEXT("Overlap with: %s"), *OtherActor->GetName()));
			OnTriggered();
		}
	}
}

 


 

3. ARedButton.h / .cpp

빨간 버튼 오브젝트를 위한 클래스를 구현해주었습니다. 추가적인 구현사항은 아직 없습니다.

ARedButton.h

더보기
#pragma once

#include "CoreMinimal.h"
#include "Actor/Triggerable/TriggerableActor.h"
#include "Interface/Sequenceable.h"
#include "RedButton.generated.h"

UCLASS()
class VIRTUALREALITY_API ARedButton : public ATriggerableActor, public ISequenceable
{
	GENERATED_BODY()
	
public:
	ARedButton();
	
public:
	virtual void OnSequenceStarted() override;
	virtual void OnSequenceEnded() override;
	
protected:
	virtual void OnTriggered() override;
	
protected:
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "변수|컴포넌트")
	TObjectPtr<UStaticMeshComponent> ButtonMesh;
	
};

ARedButton.cpp

더보기
#include "RedButton.h"

ARedButton::ARedButton()
{
	// 버튼 메시 컴포넌트를 생성하고 루트에 부착합니다.
	ButtonMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Button"));
	ButtonMesh->SetupAttachment(Mesh);
}

void ARedButton::OnSequenceStarted()
{
	GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Red, TEXT("Red Button Sequence Started"));
}

void ARedButton::OnSequenceEnded()
{
	GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Red, TEXT("Red Button Sequence Ended"));
}

void ARedButton::OnTriggered()
{
	Super::OnTriggered();
	
	PlaySequence();
}

 


 

마무리

하루종일 Procedural Grip 모션에 대해서 이것저것 찾아보다가 뭐라도 구현해야겠다 싶어서 버튼을 하나 구현했습니다. ActorSequence가 Experimental 기능이라 여러 프로젝트에서 참 아픈 손가락처럼 다가왔었는데, 이번 VR 프로젝트 덕분에 ActorSequence에 범용적으로 활용할 수 있는 인터페이스를 설계해놔서 한시름 놓을 수 있을 것 같네요 ㅎㅎ

'Unreal Engine 프로젝트 > VR 공포게임' 카테고리의 다른 글

[언리얼엔진] 6. VR Hand 애니메이션 제작  (0) 2026.04.09
[언리얼엔진] 5. VR 최적화  (0) 2026.04.09
[언리얼엔진] 4. VR 레버 구현  (2) 2026.04.08
[언리얼엔진] 3. VR Hand 물리 효과 구현  (0) 2026.04.04
[언리얼엔진] 1. VR Grab/Release 기능 구현 (C++)  (0) 2026.04.04
'Unreal Engine 프로젝트/VR 공포게임' 카테고리의 다른 글
  • [언리얼엔진] 5. VR 최적화
  • [언리얼엔진] 4. VR 레버 구현
  • [언리얼엔진] 3. VR Hand 물리 효과 구현
  • [언리얼엔진] 1. VR Grab/Release 기능 구현 (C++)
Meoyoung's Development Logs
Meoyoung's Development Logs
내가 보려고 만든 블로그
  • Meoyoung's Development Logs
    이게뭐영
    Meoyoung's Development Logs
  • 전체
    오늘
    어제
    • 분류 전체보기 (289)
      • Unreal Engine 프로젝트 (36)
        • 더 퍼스트 버서커 : 카잔 (16)
        • VR 공포게임 (13)
        • Paper-ZD (7)
      • 언리얼 엔진 (72)
        • GAS (10)
        • 트러블슈팅 (27)
        • 캐릭터 (2)
        • VR (1)
        • Lighting (2)
        • 멀티스레드 (2)
        • Lyra (1)
      • C++ (31)
        • 문법 정리 (8)
        • [서적] Fundamental C++ 프로그래밍 .. (5)
        • [서적] 이것이 C++이다 (11)
        • [서적] Effective C++ (7)
      • 게임잼 (3)
      • 강의 (36)
        • [강의] 이득우의 언리얼 프로그래밍 Part1 (13)
        • [강의] 이득우의 언리얼 프로그래밍 Part2 (2)
        • [강의] 이득우의 언리얼 프로그래밍 Part3 (12)
        • [강의] 소울라이크 개발 A-Z (4)
        • [강의] Udemy-2D (5)
      • C# (1)
        • [서적] 이것이 C#이다 (1)
      • 코딩테스트 (26)
        • 프로그래머스 (6)
        • 알고리듬 (13)
        • 자료구조 (7)
      • 컴퓨터 과학 (27)
        • 운영체제 (11)
        • 데이터베이스 (0)
        • 디자인패턴 (0)
        • 자료구조 (5)
        • 네트워크 (0)
        • 컴퓨터구조 (11)
      • 면접준비 (0)
        • C++ (0)
        • 운영체제 (0)
        • 자료구조 (0)
      • 기타 (48)
        • [팀프로젝트] The Fourth Descenda.. (5)
        • GetOutOf (15)
        • [개인프로젝트] FPS 구현 맛보기 (5)
        • [서적] 인생 언리얼5 (4)
        • 스파르타코딩클럽 (15)
        • 객체지향프로그래밍 (2)
        • 컴퓨터회로 (2)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    자료구조
    알고리즘
    셸정렬
    게임잼
    경북게임잼
    참가후기
    게임개발
    쉘정렬
    삽입정렬
    선택정렬
    버블정렬
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
Meoyoung's Development Logs
[언리얼엔진] 2. VR 버튼 구현
상단으로

티스토리툴바