초보 코린이의 성장 일지

UE4 Slate UI, Plug In 본문

언리얼

UE4 Slate UI, Plug In

코오린이 2023. 4. 3. 14:23

언리얼에 기본적으로 사용할 수 있는 플로그인이 아닌, 자체적으로 기능을 만들어 볼 것이다.

플러그인이라는 개념은 여러 모듈을 만들어 배포한다고 생각하면 된다.

1. 기본적으로 템플릿 내려보기로 생성해서 시작해 보겠다.

 

1. 기본적인 왼쪽에 플러그인들은 엔진 폴더안에 있는 기능들을 보여주고있다.

2. 새로운 사용자에 플러그인을 만들기 위해 오른쪽 하단에 새 플러그인을 클릭해 만들어준다.

3. 기본으로 설정하고 Example라고 이름을 지어 생성해준다.

 

1. 만들어준 플러그인을 보면 폴더안에 h와 cpp가 분활되어 있는걸 볼 수 있다.

2. 헤더는 모듈을 나눠줄때 dll로 컴파일해서 주게된다. 그때 어떠한 함수가 dll안에 있는지 모르기 때문에 publid로 .h만 지원해준다. cpp는 안에 내부적인 코드 및 정보 유출이 될 수 있기 때문에 private로 숨겨둔다.

3. 지금 당장은 체게적으로 다루기보다는 기초적인 부분을 다뤄야하므로 편리성을 위해 하나로 묶어줄 것이다.

1. 우선 두개를 선택 후 제거해준다.

2. 프로젝트 폴더로 들어가서 private, public 안에 내용물을 그 전 폴더로 옮겨주고 제거해준다.

3. 옮겨놓은 h, cpp를 드래그해서 c++ Example 폴더안으로 넣어준다.

 

 

1. 플러그인을 시작하는 시작점인 클래스는 반드시 IModuleInterface를 상속 받고 있어야 한다.

2. 클래스를 생성할때 new, A를 붙여서 생성했었다. 플러그인은 new Object로 상속받은 클래스들이 아니기 때문에 붙지 않는다. 그래서 관례상 클래스 앞에 F를 붙인다.

3. 대신 F가 붙는 이유는 new Object로 부터 상속받지 않는 모든 클래스들은 다 F가 붙는다.

4. StartupModule는 시작할때를 알리고, ShutdownModule는 끝이났음을 알려 줄 것이다.

 

1. 빌드를 설정해주는 곳인데 문법이 C# 문법을 띄고 있어서, 변경해 줄 것이다.

PublicIncludePaths = Private와 반대로 접근이 가능해서 보이므로 사용이 가능하다.

PrivateIncludePaths = 외부 프로젝트에서 접근할때 Include를 사용할 수 없다, private기 때문에 모듈 디렉터리가 포함되어 있는걸 알 수가없다. 그래서 만약 가져다가 쓰려고 할때 외부에서는 소스로 판단하게 될 수 있다. 왜냐면 숨겨져 있기 때문에 기본상태가 소스로 보이게된다.

다만 게임제작에 있어서는 철저하게 지켜줘야한다. 지금은 다양하게 다뤄보기 위한 것이므로, 상관이없다.

 

더보기
using UnrealBuildTool;

public class Example : ModuleRules
{
	public Example(ReadOnlyTargetRules Target) : base(Target)
	{
		PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs;

        // 모듈 디렉토리를 추가해준다.
        PublicIncludePaths.Add(ModuleDirectory);

        // 외부에서 항상 접근하므로, Core는 열어준다.
        PublicDependencyModuleNames.Add("Core");

        // 외부에서 알 수 없어야 하므로, 숨겨준다.
        PrivateDependencyModuleNames.Add("CoreUObject");
        PrivateDependencyModuleNames.Add("Engine");
        PrivateDependencyModuleNames.Add("Slate");
        PrivateDependencyModuleNames.Add("SlateCore");
        PrivateDependencyModuleNames.Add("GameplayDebugger");

    }
}

1. Add를 사용해서 변경해준다.

 

Example.cpp

1. 만든 플러그인이 잘 출력되는지 확인하기 위해 Warning를 사용하여 확인해보겠다.

2. Warning를 사용하는 이유는 노란색으로 출력되기 때문에 확인할때 보기 편하다.

3. FExampleModule Startup가 출력되는걸 볼 수 있다.

1. 로그들에 출력 기록을 보고 싶을때는 위에 폴더로 들어가서 확인하면 알 수 있다.

 

1. 플레이시 위에 어떠한 상태를 보여주는 기능을 만들기 위해, 사전작업을 들어갈 것이다.

2. 클래스 추가를 눌러서 없음을 선택한다 -> 이름을 지어주고 오른쪽에 Runtime을 눌러 이름이 Example인 플러그인 폴더로 변경하고 생성해준다.

 

 

더보기
#pragma once

#include "CoreMinimal.h"
#include "Modules/ModuleManager.h"

class FExampleModule : public IModuleInterface
{
public:
	virtual void StartupModule() override;
	virtual void ShutdownModule() override;

};
#include "ExampleModule.h"
#include "ExampleDubuggerCategory.h"

#include "GameplayDebugger.h" // 언리얼 헤더

#define LOCTEXT_NAMESPACE "FExampleModule"

IMPLEMENT_MODULE(FExampleModule, Example)

void FExampleModule::StartupModule()
{
	IGameplayDebugger::FOnGetCategory category;
	// 선언과 함께 초기화하려면 Create 사용, 그게 아니라면 Bind 사용
	category.BindStatic(&FExampleDubuggerCategory::MakeInstance); // static로 객체가 필요없으므로 주소만 넣어준다.

	// 싱글톤 Get(), Delegete 이므로 이벤트이다.
	// OnGet이 붙으면, static를 MakeInstance로 return 해준다고 생각하면 된다.
	// EGameplayDebuggerCategoryState 어떠한 상황에서 활성화 할껀지 체크
	// 마지막 매개변수는 슬롯으로 내가 원하는 번호에 할당한다.
	IGameplayDebugger::Get().RegisterCategory("Example", category, EGameplayDebuggerCategoryState::EnabledInGameAndSimulate, 5);
	IGameplayDebugger::Get().NotifyCategoriesChanged();
}

void FExampleModule::ShutdownModule()
{
	// 항상 할당을 했으면, 제거되어야 하는게 있는지 반드시 확인해줘야한다.
	// 그렇지 않으면 에디터상에 항상 남아있는다.
	if (IGameplayDebugger::IsAvailable())
		IGameplayDebugger::Get().UnregisterCategory("Example"); // 카테고리에서 해제

}

#undef LOCTEXT_NAMESPACE

1. 플로그인은 죄다 이벤트화가 되어있기 때문에 스마터포인터와 델리게이트로 이뤄져있다고 생각하면 된다.

2. 할당을 해줘서 5번 슬롯에 등록시킨다.

 

 

추가 전
추가 후

1. 5번 슬롯에 Example가 들어온걸 확인할 수 있다.

1. 세팅 -> 프로젝트 세팅 -> 엔진: 게임플레이 디버거 -> 하단 Add Ons 카테고리에 보면 5번 슬롯에 등록되어 있는걸 확인 할 수 있다.

1. FGameplayDebuggerCategory -> f12 -> 타고 들어가서 가져온 함수

2. replication은 네티워크에 핵심적인 부분이다. gather이 붙어있는 뜻 그대로 데이터를 모아주는 의미기도 한다.

더보기
#pragma once

#include "CoreMinimal.h"
#include "GameplayDebuggerCategory.h"

class EXAMPLE_API FExampleDubuggerCategory
	: public FGameplayDebuggerCategory // 사용하기 위해 상속
{
public:
	FExampleDubuggerCategory();
	~FExampleDubuggerCategory();

public:
	// 레지스터들은 객체 생성을 해줄것이기 때문에 static로 생성해준다.
	// 필요할때 객체를 생성하기 위해 사용
	static TSharedRef<FGameplayDebuggerCategory> MakeInstance();

public:
	void CollectData(APlayerController* OwnerPC, AActor* DebugActor) override;

};
#include "ExampleDubuggerCategory.h"
#include "GameFramework/Character.h"
#include "GameFramework/PlayerController.h"

FExampleDubuggerCategory::FExampleDubuggerCategory()
{

}

FExampleDubuggerCategory::~FExampleDubuggerCategory()
{

}

TSharedRef<FGameplayDebuggerCategory> FExampleDubuggerCategory::MakeInstance()
{
	// 자기자신껄 만들어서 return.
	return MakeShareable(new FExampleDubuggerCategory());
}

void FExampleDubuggerCategory::CollectData(APlayerController* OwnerPC, AActor* DebugActor)
{
	// 에디터에서는 부모 호출할때 Super를 사용하면 안된다. Super은 동적인 에디터 상황일때만 사용
	// 부모클래스 그대로 사용하면 된다.
	FGameplayDebuggerCategory::CollectData(OwnerPC, DebugActor);

	// OwnerPc - 플레이어 -> GetPawn - 컨트롤러가 빙의한 폰 -> GetName - 이름
	// 매프레임 실행된다.
	//GLog->Log(OwnerPC->GetPawn()->GetName());

	// 디버그 사용안하면 없앨수도 있기 때문에 null 체크를 해준다.
	if (!!DebugActor)
		GLog->Log(DebugActor->GetName());


}

1. 가상인 함수를 가져와서 사용

 

다음에 더 깊게 다뤄볼 것이다.

'언리얼' 카테고리의 다른 글

UE4 Console, Command  (0) 2023.04.05
UE4 DrawDebugLine  (0) 2023.04.04
UE4 FPS IK, Pistol  (0) 2023.04.01
UE4 FPS Pistol  (0) 2023.03.31
UE4 FPS AK47, DotSight  (0) 2023.03.30
Comments