상세 컨텐츠

본문 제목

언리얼 엔진 - C++로 객체 코드 작성하기

언리얼엔진

by zmo 2024. 10. 5. 17:03

본문

몇주간 공부하던 내용들 (연산자 오버로딩, 람다 표현식, 예외처리등)을 어떤 코드를 작성해보아야 잘 사용해 볼수 있을까 생각해보았다

하지만 연산자 오버로딩의 경우 복잡한 수학적 연산을 처리함에 유용한데 언리얼 엔진에서는 FVector과 같은 구조체에는 오버로딩이 구현되어 있고 따로 커스텀 클래스를 만들기에는 살짝 어려움이 있어 람다 표현식과 예외처리를 할수 있는 코드를 작성해보기로 하였다

오늘 작성해볼 코드는 충돌시 깜박이는 이벤트를 발생시키는 물체이다

다음의 링크를 참조하여 언리얼에서 사용하는 코드의 규칙을 바탕으로 작성해보았다(하도 길어서 놓친 부분이 있을수 있다)(https://dev.epicgames.com/documentation/ko-kr/unreal-engine/epic-cplusplus-coding-standard-for-unreal-engine?application_version=5.1)

 

오늘 알아보기

1. 충돌시 깜박이는 물체 코드

2. 코드 알아보기

3. 코드 작성중 알게 된점

 


 

 

충돌시 깜박이는 물체(충돌 이벤트, 물체 가시성 조절)

헤더 파일: FlickeringActor.h

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "FlickeringActor.generated.h"

UCLASS()
class YOURPROJECTNAME_API AFlickeringActor : public AActor
{
    GENERATED_BODY()

public:
    AFlickeringActor();

protected:
    virtual void BeginPlay() override;

public:
    virtual void Tick(float DeltaTime) override;

    UFUNCTION()
    void OnHit(UPrimitiveComponent* HitComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit);

private:
    UPROPERTY(EditAnywhere)
    float FlickerDuration = 3.0f;  // 깜박임 지속 시간

    bool bFlickering = false;      // 깜박임 상태
    float TimeSinceFlicker = 0.0f; // 깜박임 경과 시간
};

 

 

CPP 파일: FlickerringActor.cpp

#include "FlickeringActor.h"
#include "Components/StaticMeshComponent.h"
#include "GameFramework/Actor.h"
#include "Engine/World.h"
#include "TimerManager.h"
#include "Math/UnrealMathUtility.h"

// 생성자
AFlickeringActor::AFlickeringActor()
{
    PrimaryActorTick.bCanEverTick = false; // 처음엔 Tick 비활성화

    // 충돌을 처리하기 위해 Static Mesh Component 설정
    UStaticMeshComponent* Mesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("MeshComponent"));
    Mesh->SetSimulatePhysics(true);
    Mesh->SetNotifyRigidBodyCollision(true);
    Mesh->BodyInstance.SetCollisionProfileName("BlockAll");
    Mesh->OnComponentHit.AddDynamic(this, &AFlickeringActor::OnHit);
    RootComponent = Mesh;
}

// 게임 시작 시 호출되는 함수
void AFlickeringActor::BeginPlay()
{
    Super::BeginPlay();
}

// 매 프레임 호출되는 Tick 함수
void AFlickeringActor::Tick(float DeltaTime)
{
    Super::Tick(DeltaTime);

    if (bFlickering)
    {
        // 깜박임 경과 시간 업데이트
        TimeSinceFlicker += DeltaTime;

        // 깜박임이 계속되는 동안
        if (TimeSinceFlicker < FlickerDuration)
        {
            // 람다 표현식을 사용하여 가시성을 토글
            auto ToggleVisibility = [this](bool bIsVisible)
            {
                SetActorHiddenInGame(!bIsVisible);
            };

            // Fmod 함수로 0.1초마다 가시성 변경
            bool bIsVisible = FMath::Fmod(TimeSinceFlicker, 0.1f) < 0.05f;
            ToggleVisibility(bIsVisible);
        }
        else
        {
            // 깜박임 종료 시 Tick 비활성화 및 가시성 복원
            bFlickering = false;
            SetActorHiddenInGame(false); // 물체를 보이게 설정
            SetActorTickEnabled(false);  // Tick 비활성화
        }
    }
}

// 충돌 시 호출되는 함수
void AFlickeringActor::OnHit(UPrimitiveComponent* HitComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit)
{
    // 깜박임 상태 초기화 및 Tick 활성화
    bFlickering = true;
    TimeSinceFlicker = 0.0f;
    SetActorTickEnabled(true); // 충돌 시 Tick을 활성화하여 깜박임 처리
}

 


 

코드 알아보기

 

 

주석에도 달려있고 너무 간단한 내용이지만 따로 정리해보기로 한다 (C++ 파일 위주로 보면된다)

 

 

1. SetActorTickEnabled 활용하기

 

PrimatyActorTick.bCanEverTick = false 로 설정하여, 객체가 처음 생성될 때는 Tick 함수가 비활성화되도록 하고

bCanEverTick 변수를 설정하여 충돌시 활성화하였다가 깜박임이 종료되면 비활성화 시키도록 함으로 맵이 불필요한 연산을 수행하지 않게끔 해보았다

 

2. 람다 표현식 사용하기

ToggleVisibility 람다 함수를 통해 물체의 가시성을 변경하였다

SetActorHiddenInGame를 통해 물체를 숨기거나 다시 보이게 할수 있다

 


 

추가로 알게 된점

 

위의 코드와 같이 include를 통해 들여오는 헤더 파일들을 일정 부분 직접 작성해야 하는줄 알았으나 언리얼 엔진에서 기본적으로 많이 라이브러리들을 제공해주어서 편하게 작성할수 있었다 다음은 C++ 코드에서 사용한 헤더 파일들의 역할이다

 

 

FlickeringActor.h

Unreal Engine의 핵심 기능과 C++ 표준 라이브러리의 기본적인 부분을 포함하는 헤더 파일이다

 

Components/StaticMeshComponent.h

물체의 외형을 그리기 위한 컴포넌트

물체의 충돌 및 렌더링 작업에 주요 사용되며 3D 오브젝트를 렌더링 하는데 필수적이다

 

GameFramework/Actor.h

Unreal Engine에서 모든 액터(게임 오브젝트)의 기본 클래스이다

 

Engine/World.h

게임의 전체 월드를 관리하며, 타이머 설정이나 게임 내에서 월드와 관련된 작업을 할 때 사용한다

 

TimerManager.h

타이머 설정 및 제어를 위한 유틸리티 클래스

주기적으로 반복되거나 일정시간 후에 실행하는 작업을 지정할수 있다

 

Math/UnrealMathUtility.h

수학 관련 유틸리티 함수들을 제공한다

난수 생성, 나머지 연산, 삼각 함수 등등

 

 

 

관련글 더보기