프로그래밍 공부
작성일
2024. 4. 3. 12:24
작성자
WDmil
728x90

언리얼 C++로도 블루프린트 처럼 함수 오버라이드가 가능하다.


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

#pragma once

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

class UBoxComponent;
class UTextRenderComponent;

UCLASS()
class SUBPROJECT_API AC07_override : public AActor
{
	GENERATED_BODY()
	
	UPROPERTY(VisibleDefaultsOnly)
	USceneComponent* Scene;

	UPROPERTY(VisibleDefaultsOnly)
	UBoxComponent* Box;

	UPROPERTY(VisibleDefaultsOnly)
	UTextRenderComponent* Text;

protected:
	UPROPERTY(BlueprintReadWrite)
	UStaticMeshComponent* Mesh;

	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	bool bIsOverride;

public:	
	// Sets default values for this actor's properties
	AC07_override();

protected:
	// Called when the game starts or when spawned
	virtual void BeginPlay() override;

	// C++에서 바디 구현이 가능
	UFUNCTION()
	void OnBeginOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, 
		UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, 
		const FHitResult& SweepResult);

	UFUNCTION()
	void OnEndOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, 
		UPrimitiveComponent* OtherComp, int32 OtherBodyIndex);

protected:
	// C++과 블루프린트 모두에서 오버라이딩이 가능한 함수
	UFUNCTION(BlueprintNativeEvent)
	void ChangeColorWhite();
	
    // 블루프린트 에서만 오버라이딩이 가능한 경우
	UFUNCTION(BlueprintImplementableEvent)
	void ChangeColorRed();

private:
	void ChangeColorWhite_Implementation();

};

 

각 Proteccted에 선언된 UFUNCTION의 내부지정자에 따라 오버라이딩 경우가 달라진다.

protected:
	// C++과 블루프린트 모두에서 오버라이딩이 가능한 함수
	UFUNCTION(BlueprintNativeEvent)
	void ChangeColorWhite();

	// 블루프린트 에서만 오버라이딩이 가능한 경우
	UFUNCTION(BlueprintImplementableEvent)
	void ChangeColorRed();

private:
	// C++에서 오버라이딩 할 시 뒤에 Implementation을 붙여준다.
	void ChangeColorWhite_Implementation();

};

함수를 선언할 때, UFUNCTION에 대한. 오버라이딩이 가능한 경우, 블루프린트에서만 가능한 경우 를 구분지어 선언해주면 된다.

 

C++에서 오버라이딩 할 시 Implementation을 붙여서 선언하면, 언리얼 컴파일러가 알아서 오버라이드 선언으로 간주한다.

 

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


#include "C07_override.h"
#include "Utillites/Helper.h"

#include "Components/BoxComponent.h"
#include "Components/TextRenderComponent.h"

#include "Materials/MaterialInstanceConstant.h"
#include "Materials/MaterialInstanceDynamic.h"

#include "Kismet/KismetMathLibrary.h"
// Sets default values
AC07_override::AC07_override()
{
	Scene = Helper::CreateSceneComponent<USceneComponent>(this, "Scene");
	Box = Helper::CreateSceneComponent<UBoxComponent>(this, "Box", Scene);
	Box->SetRelativeScale3D(FVector(3));
	Box->bHiddenInGame = false;

	Text = Helper::CreateSceneComponent<UTextRenderComponent>(this, "Text", Scene);
	Text->SetRelativeRotation(FRotator(0, 180, 0));
	Text->SetRelativeLocation(FVector(0, 0, 120));
	Text->SetHorizontalAlignment(EHorizTextAligment::EHTA_Center);
	Text->SetVerticalAlignment(EVerticalTextAligment::EVRTA_TextCenter);
	Text->Text = FText::FromString(GetName().Replace(L"Default__", L""));
	Text->SetTextRenderColor(FColor::Blue);

	Mesh = Helper::CreateSceneComponent<UStaticMeshComponent>(this, "Mesh", Scene);
	Mesh->SetStaticMesh(Helper::GetAsset<UStaticMesh>("/Script/Engine.StaticMesh'/Game/Sphere.Sphere'"));
	Mesh->SetRelativeLocation(FVector(250, 0, 0));
	Mesh->SetMaterial(0, Helper::GetAsset<UMaterialInstanceConstant>("/Script/Engine.MaterialInstanceConstant'/Game/M_Mesh_Inst.M_Mesh_Inst'"));
}

// Called when the game starts or when spawned
void AC07_override::BeginPlay()
{
	Super::BeginPlay();
	
	Box->OnComponentBeginOverlap.AddDynamic(this, &AC07_override::OnBeginOverlap);
	Box->OnComponentEndOverlap.AddDynamic(this, &AC07_override::OnEndOverlap);

	Text->SetText(FText::FromString(UKismetSystemLibrary::GetDisplayName(this)));

	UMaterialInstanceDynamic* Material = UMaterialInstanceDynamic::Create(Mesh->GetMaterial(0), this);
	Mesh->SetMaterial(0, Material);

}

void AC07_override::OnBeginOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
	ChangeColorRed();
}

void AC07_override::OnEndOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex)
{
	ChangeColorWhite();
}

void AC07_override::ChangeColorWhite_Implementation()
{
	Cast<UMaterialInstanceDynamic>(Mesh->GetMaterial(0))->SetVectorParameterValue("Color", FColor::White);
}

 

현재 동작사항은, Collision이 동작하였을 시, Mesh의 Instance 머티리얼의 색을 바꾸어주는 동작이다.

 

ChangeColorWhite의 경우, 함수의 선언이 이루어지지 않았지만, Implementation함수 선언으로 인해, 오버라이드 되어, 색이 바뀌게 된다.

 

ChangeColorRed()의 경우 블루프린트 로 동작하며, 함수가 오버라이드 되어 색이 바뀌게 된다.

테스트

728x90