본문 바로가기
프로그래밍 이야기/GameDev

[Unreal Engine] WebBrowser Plugin 사용하기

by Mulder5 2021. 5. 13.
반응형

게임 개발자도 손쉽게 Unreal Engine으로 하이브리드 앱을 만들 수 있다. 물론 더 쉬운 방법이 있긴 하겠으나 게임 개발자들에게 매우 익숙한 Unreal Engine을 그대로 사용해서! WebBrowser 플러그인을 사용한다면 아주 손쉽고 간단하게 만들 수 있겠다.

 

프로젝트 생성하기

웹브라우징이 메인 컨텐츠가 될 것이니, 아래와 같이 완전히 비어이있는 프로젝트로 시작한다. 

Games 선택
Blank 선택
C++, No Starter Content 선택

 

WebBrowser Plugin 활성화 하기

Settings > Plugins 를 선택

Settings > Plugins

 

"Web Browser"를 검색하여 찾고, Enabled를 체크하고, Restart Now 를 클릭하여 재시작 한다. 

Web Browser를 클릭하여 플러그인을 활성화

 

프로젝트 경로 > Source / WebBrowserDemo / WebBrowserDemo.Build.cs 를 아래와 같이 수정한다. 

"UMG", "WebBrowser", "Slate", "SlateCore"를 추가한다.

PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "UMG", "WebBrowser" });

PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" });

 

WebBrowserDemo.uproject 파일을 우클릭하고, Generate Visual Studio project Files를 선택하여 Visual Studio 프로젝트 파일을 갱신한다. 

 

 

WebBrowser를 상속받는 클래스 생성하기

WebBrowser클래스를 상속받는 클래스를 만들것이다. 하지만 이 클래스를 직접 사용하지는 않을 것이다. 이 서브 클래스를 만드는 이유는 이렇게 한번이라도 WebBrowser 플러그인의 서브클래스가 생성되어야 내가 작성할 cpp 파일에서 Include가 가능해지기 때문이다.

WebBrowserDemo.uproject를 더블클릭하여 Unreal Editor를 열고, Content Browser > C++ Classes 에서 우클릭 > New C++ Class를 선택하여 새로운 클래스를 만든다.

New C++ Class...

 

Add C++ Class 다이얼로그에서 Show All Classes를 체크하고 "WebBrowser" 검색, 선택한다. 

 

클래스 이름을 입력하고 클래스를 생성한다. (MyWebBrowser)

정상적으로 클래스가 생성 되었다면 자동으로 컴파일이 수행되며, 문제없이 컴파일이 된다.

만약 나중에 WebBrowser 클래스를 재정의해서 사용할 계획이라면 이 클래스를 사용해도 되지만 본 예제에서는 이를 사용하지 않고 MyWebBrowser의 부모 클래스인 WebBrowser 클래스를 직접 사용하고자 한다. 그러므로 삭제 해도 좋다.

 

WebBrowser를 사용하여 화면에 출력할 Widget 클래스 만들기

이번엔 "UserWidget"을 상속 받는 "WebBrowserWidget" 라는 이름으로 클래스를 만든다.

생성된 WebBrowserWidget 클래스

 

 

WebBrowserWidget을 화면에 출력하기

WebBrowserWidget을 화면에 출력하기 위해서는 GameMode 상에서 WebBrowserWidget을 생성하고 AddToViewPort를 수행하고 프로젝트의 기본 GameMode를 선택해주면 된다.

WebBrowserDemoGameModeBase의 구현

기본 생성되어있는 AWebBrowserDemoGameModeBase 에 BeginPlay()를 구현한다.

WebBrowserDemoGameModeBase.h

class WEBBROWSERDEMO_API AWebBrowserDemoGameModeBase : public AGameModeBase
{
	GENERATED_BODY()
		virtual void BeginPlay() override;
	
};

WebBrowserDemoGameModeBase.cpp

#include "WebBrowserDemoGameModeBase.h"

void AWebBrowserDemoGameModeBase::BeginPlay()
{
}

 

다음과 같이 출력할 Widget 객체를 선언하고 구현한다.

WebBrowserDemoGameModeBase.h

class WEBBROWSERDEMO_API AWebBrowserDemoGameModeBase : public AGameModeBase
{
	GENERATED_BODY()
		virtual void BeginPlay() override;


protected:
	// 블루프린트 상에서 설정할 수 있는 속성이 된다.
	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "WebBrowser", Meta = (BlueprintProtected = "true"))
		TSubclassOf<class UUserWidget> WebBrowserWidgetClass;

	UPROPERTY()
		class UUserWidget* CurrentWidget;
	
};

WebBrowserDemoGameModeBase.cpp

#include "WebBrowserDemoGameModeBase.h"
#include "Blueprint/UserWidget.h"

void AWebBrowserDemoGameModeBase::BeginPlay()
{
	Super::BeginPlay();

	// WebBrowserWidget을 화면에 출력
	if (WebBrowserWidgetClass != nullptr)
	{
		CurrentWidget = CreateWidget<UUserWidget>(GetWorld(), WebBrowserWidgetClass);

		if (CurrentWidget != nullptr)
		{
			CurrentWidget->AddToViewport();
		}
	}
}

 

WebBrowserDemoGameModeBase의 Blueprint 클래스 생성

편집한 파일들을 모두 저장하고 코드에 문제가 없는지 컴파일해보고, 다음과 같이 WebBrowserDemobase 클래스에 대한 Blueprint 클래스를 생성한다. WebBrowserDemoGameModeBase 클래스를 우클릭하고 "Create Blueprint class based on WebBrowserDemoGameModeBase"를 선택한다.

Content 경로 아래에 UI 폴더를 미리 생성했으며 이 경로를 지정했다. 클래스 이름에는 보통 BP 키워드를 사용한다. 접두어로 "BP_"를 붙여서 Blueprint 클래스를 생성한다.

 

WebBrowserWidget 클래스의 Blueprint 클래스 생성

Content Browser의 Content > UI 경로에서 우클릭하여 Blueprint Class를 선택한다.

부모 클래스로서 WebBrowserWidget을 선택하고, 이름을 "BP_WebBrowserWidget"으로 입력해준다. 각 Blueprint 객체들을 모두 저장해주고 컴파일을 해준다.

BP_WebBrowerDemoGameModeBase와 BP_WebBrowerWidet 클래스가 생성되었다. 컴파일하고 문제가 없는지 확인한다.

 

초기화 시점에서 출력할 GameMode 및 Widget 의 설정

기본 GameMode를 선택해주기 위해서 Unreal Editor 메뉴 > Edit > Project Settings 를 선택한다. 

Project > Maps & Modes > Default Maps 에서 BP_WebBrowserDemoGameModeBase를 선택한다.

 

이번엔 Content Browser에서 BP_WebBrowserDemoGameModeBase를 더블클릭하여 속성을 편집한다.

BP_WebBrowserDemoGameModeBase 속성들 중에서 WebBrowser > Web Browser Wdiget Class를 선택할 수 있다. 이중 BP_WebBrowserWidget을 선택하고 Blueprint 다이얼로그 내의 Compile, Save를 수행한다.

위의 설정들로 인해서 게임 프로젝트는 게임 시작 시에 BP_WebBrowserDemoGameModeBase를 기본 GameMode로 열게되고 이 GameMode는 BP_WebBrowserWidget을 생성, 출력하게 된다.

 

BP_WebBrowserWidget에서 UI 그리기

Content Browser의 BP_WebBrowserWidget을 더블클릭하여 편집 모드로 진입하고 Canvas Panel 스크린 상에 드래그앤 드롭하여 배치한다. Canvas Panel은 cpp 상에서 접근 및 제어는 불필요하므로 인스턴스의 이름은 따로 수정하지 않아도 된다. 

 

Palette에서 WebBrowser를 검색하여 "WebBrowser"를 배치한다. (My Web Browser를 사용해도 무방하나 본 예제에서는 WebBrowser를 사용한다.) Anchors 및 Offset 설정을 수정하여 전체 화면으로 출력하였다.

Appearance > Initial URL 값으로 "www.google.com"을 입력해준다.

Blueprint를 컴파일, 저장하고 Play를 클릭하여 게임을 시작해보자. 아래와 같이 WebBrowserWidget에서 Google을 잘 출력되는지 확인한다. 

 

WebBorwserWidet에 주소 입력 기능 만들기

위의 기능만으로는 원하는 주소를 애플리케이션 실행중에는 변경할 수 없다. 이를 위해 주소 입력창을 만들어보자.

BP_WebBrowserWidget 편집하기

Content Browser에서 BP_WebBrowserWidget을 더블클릭하여 편진모드로 진입한다. 
Web_Display의 Offset Top > 50 을 입력하여 화면 상단에 주소 입력을 위한 공간을 비운다. 

Palette에서 Text Box를 드래그앤드랍하여 배치하고, 상단에 꽉차게 위치 설정을 해준다.
인스턴스 이름은 "Edit_URLInput"으로 입력한다. 
Font > Size 를 20으로 설정해서 글자 크기가 잘 보이도록 크게 만들어준다. 

BluePrint를 컴파일>저장해주고 Play를 클릭해서 주소 입력을 위한 EditBox가 잘 출력되는지 확인한다. 

 

WebBrowserWidget의 기능구현

이번엔 C++ 상에서 기능 구현을 해보자. Content Browser > C++ Classes > WebBrowserDemo > WebBroserWidget을 더블클릭하면 Visual Studio 에서 WebBrowserWidget.cpp 가 열린다. 우선  WebBrowserWidget.h를 열어서 다음과 같이 수정한다. 

WebBrowserWidget.h

#include "CoreMinimal.h"
#include "Blueprint/UserWidget.h"
#include "WebBrowserWidget.generated.h"

UCLASS()
class WEBBROWSERDEMO_API UWebBrowserWidget : public UUserWidget
{
	
	GENERATED_BODY()
    
    	// 생성 > 초기화
	virtual void NativeConstruct() override;

	// WebBrowser 인스턴스
	UPROPERTY(meta = (BindWidget))
	class UWebBrowser* Web_Display;

	// 주소 입력창 인스턴스
	UPROPERTY(meta = (BindWidget))
	class UEditableTextBox* Edit_URLInput;
	
};

WebBrowserWidget.cpp

#include "WebBrowser.h"
#include "WebBrowserWidget.h"
#include "Runtime/UMG/Public/Blueprint/UserWidget.h"
#include "Runtime/UMG/Public/Components/EditableTextBox.h"
#include "Runtime/UMG/Public/Components/Button.h"


void UWebBrowserWidget::NativeConstruct()
{
	Super::NativeConstruct();

	UE_LOG(LogTemp, Warning, TEXT("LHH - UWebBrowserWidget::Construct_Implementation"))


	// 초기화
	const FString initialURL = TEXT("www.naver.com");

	// 초기 URL을 입력창에 입력
	if (this->Edit_URLInput != nullptr)
	{
		Edit_URLInput->SetText(FText::FromString(initialURL));
	}

	// 초기 URL 웹브라우저에서 열기
	if (this->Web_Display != nullptr)
	{
		this->Web_Display->LoadURL(initialURL);
	}
}

이번엔 초기화 URL을 Naver로 입력 했고, 이 주소가 주소 입력창에도 표시되고, 웹브라우저에도 적용되도록 WebBrowser의 LoadURL을 호출했다.

Unreal Editor에서 컴파일하고, 게임을 실행해보자. 아래와 같이 초기 URL로 설정한 Naver가 출력된다.

그런데 아직은 주소 입력에 대한 이벤트 트리거와 핸들러가 준비되지 않았다. 이를 위한 구현을 추가한다.

 

WebBrowserWidget.h

#include "CoreMinimal.h"
#include "Blueprint/UserWidget.h"
#include "WebBrowserWidget.generated.h"

/**
 * 
 */
UCLASS()
class WEBBROWSERDEMO_API UWebBrowserWidget : public UUserWidget
{
	GENERATED_BODY()

		virtual void NativeConstruct() override;

	UPROPERTY(meta = (BindWidget))
		class UWebBrowser* Web_Display;

	UPROPERTY(meta = (BindWidget))
		class UEditableTextBox* Edit_URLInput;

	// 블루프린트에서 호출 가능한 이벤트 핸들러 함수 추가
	UFUNCTION(BlueprintCallable, Category = "WebBrowserWidget")
		void OnWebBrowserURLCommitted(const FText& Text);
	
};

WebBrowserWidget.cpp

void UWebBrowserWidget::OnWebBrowserURLCommitted(const FText& Text)
{
	UE_LOG(LogTemp, Warning, TEXT("LHH - UWebBrowserWidget::OnWebBrowserURLCommitted"))
	if (this->Web_Display != nullptr)
	{
		this->Web_Display->LoadURL(Text.ToString());
	}
}

OnWebBrowserURL 함수가 호출되면 웹브라우저의 LoadURL을 호출하도록 구현되었다. 이제 Edit_URLInput의 이벤트와 WebBrowserWidget의 OnWebBrowserURLCommitted 함수의 연결을 만든다.

BP_WebBrowserWidget을 더블클릭하여 편집 모드에서 Edit_URLInput의 속성창의 제일 아래에 Evnet > on Tex Committed 가  있다. 녹색 + 버튼을 클릭한다. 

On Text Committed 이벤트 함수 박스의 [>] 버튼으로부터 드래그앤드랍을 하면 연결해줄 후보 함수들이 나열된다. 이들중 On Web Browser URLCommintted를 선택한다. 

그리고 전달되는 Text 값도 연결해준다. 이를 통해 Edit_URLInput에서 URL이 입력되면 On Web Browser URL Committed 함수가 호출되며 매개변수로서 URL 주소가 Text 변수로 전달 된다.

Blueprint를 컴파일, 저장하고 Play를 클릭하여 게임을 실행한다. Edit_URLInput 에 웹 주소를 입력하면 그 주소의 웹이 열릴 것이다.

 

웹을 여는 기능 외에 웹 내부에서 JavaScript가 잘 실행되는지, 그리고 C++에서 웹을 위한 JavaScript를 호출하는 방법에 대해서는 다음 글에서 이어가겠다. 

반응형