14
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Unreal Engine 4 (UE4)Advent Calendar 2019

Day 6

UE4 Editor コンパイル通知をDiscordに流したい話

Last updated at Posted at 2019-12-05

この記事はUnreal Engine 4(UE4) Advent Calendar 2019の6日目の投稿記事です。


目的

UE4 EditorでC++のソースをコンパイルした際の通知をDiscordで受け取りたい。

やっていくこと

  1. 空のプラグインを作成する
  2. HTTP, JsonPrivateDependencyModuleNames に追加
  3. イベントリスナを作成し、DiscordにWebhookリクエストをかけられるようにする
  4. IHotReloadInterfaceOnModuleCompilerFinished にイベントリスナをバインドする

やっていく

Discord Webhook URLの取得

Discordで任意のチャンネルにWebhookを作成します。

image.png

任意の名前やアイコンを設定し、「ウェブフックURL」をコピーしておきます。

このURLがプラグインからのリクエストに必要になります。

空のプラグイン作成

Editor -> Plugins -> New Plugins より適当な名前を設定し、プラグインを作成します。

この記事では HotReloadNotifications という名前で設定して進めていきます。

image.png

必要なモジュールの依存を追加

Visual Studio を起動して、HotReloadNotificationsModule.Build.csを編集します。

PrivateDependencyModuleNamesHTTPJson を追記します。

PrivateDependencyModuleNames.AddRange(
    new string[]
    {
        "CoreUObject",
        "Engine",
        "Slate",
        "SlateCore",
        "HTTP",
        "Json"
        // ... add private dependencies that you statically link with here ...	
    }
);

HTTP は Webhookの送信に必須で、 Json はDiscord Webhookで送信するJson文字列の生成にあると便利です。

イベントリスナの定義を作成する

HotReloadNotificationsModule.h を開き、引数が (const FString&, ECompilationResult::Type, bool) なメンバ関数を用意します。

void OnCompileFinished(const FString& LogDump, ECompilationResult::Type CompilationResult, bool bShowLog) const;

なお、 ECompilationResult::Type を使用するために Misc/CompilationResult.h をインクルードする必要があります。

#include "Misc/CompilationResult.h"

実装

続いて、 HotReloadNotificationsModule.cpp を編集していきます。

ヘッダのインクルード

HttpModule.h, Interfaces/IHttpRequest.h, Serialization/JsonSerializerMacros.h, Misc/HotReloadInterface.h の4ファイルをインクルードします。

#include "HttpModule.h" // -> HTTP Request
#include "Interfaces/IHttpRequest.h" // -> HTTP Request
#include "Serialization/JsonSerializerMacros.h" // Serialize Struct
#include "Misc/HotReloadInterface.h" // -> Listen HotReload Event
イベントリスナのバインド

IHotReloadInterface | Unreal Engine Documentation
今回はこの IHotReloadInterface より FModuleCompilerFinishedEvent にイベントをバインドして機能を作ります。

IHotReloadInterface のインスタンスを静的な関数 GetPtr() から取得します。

const auto& HotReloadModule = IHotReloadInterface::GetPtr();

FModuleCompilerFinishedEvent はメンバ関数 OnModuleCompilerFinished より取得できます。
Eventに AddRaw してバインドは完了です。

HotReloadModule->OnModuleCompilerFinished().AddRaw(this, &FHotReloadNotificationsModule::OnCompileFinished);

Webhook送信する構造体の作成

struct FDiscordWebhookRequestBody : public FJsonSerializable
{
	FString Content;

	BEGIN_JSON_SERIALIZER
		JSON_SERIALIZE("content", Content);
	END_JSON_SERIALIZER

	FDiscordWebhookRequestBody(const FString& Content) : Content(Content) {}
	FDiscordWebhookRequestBody() : FDiscordWebhookRequestBody(FString()) {}
};

このように FJsonSerializable を継承し JSON_SERIALIZE などのマクロを使って構造体を定義します。
こうすることで、ToJson 関数を呼ぶだけで FString 型のJson文字列に変換することができます。

Discord Webhook URLを書いておく

別にこれはどうだっていいんですが、先程コピーしたDicordのWebhook URLをここでコードにベタ書きします。

static constexpr auto DISCORD_WEBHOOK_URL = "<WEBHOOK_URL>";

この辺はエディタの設定拡張とかでどうにかしたかったけど面倒なので諦めました

イベントリスナの実装

OnCompileFinished の実装を書いていきます。

void FHotReloadNotificationsModule::OnCompileFinished(const FString& LogDump, ECompilationResult::Type CompilationResult, bool bShowLog) const {
    const auto Body = FDiscordWebhookRequestBody(ECompilationResult::Succeeded == CompilationResult ? FString(L"[HotReloadNotifications] COMPILE SUCCEEDED") : FString(L"[HotReloadNotifications] COMPILE FAILED"));
    auto Request = FHttpModule::Get().CreateRequest();
    Request->SetVerb("POST");
    Request->SetHeader("Content-Type", "application/json");
    Request->SetURL(FString(DISCORD_WEBHOOK_URL));
    Request->SetContentAsString(Body.ToJson());
    Request->ProcessRequest();
}

よくあるHTTPリクエストを組み立てて送信しているというコードです。

EComppilationResult::Type 列挙型には Succeeded 以外にもいくつかの列挙値が存在しますが、ここでは Succeeded のみの判定としています。

先程 FJsonSerializable を継承して作成した FDiscordWebhookRequestBody のインスタンスから、 ToJson 関数を使って文字列に変換しています。(めちゃくちゃ便利)

確認

Visual Studioからのビルドが完了した上で、UE4のコンパイルを実行します。

DiscordにちゃんとWebhookが飛んできていたらOKです。

image.png

まとめ

今回の成果物 ekuinox/UE4-HotReloadNotificationsはこちらです。

株式会社ヒストリアさんの[UE4] Slack連携してライトビルドの完了を通知する を読んだところ、コンパイル通知もやりたいなと思って実現したものです。(JsonやHTTP周りも大変助かりました)
ただ IHotReloadInterface にたどり着くまでには地味に時間がかかっていて、GitHub上のUE4のソースを検索かけて探しました。
UE4で用意されたクラスの使用例が見たくて検索かけてんのにエンジンのクローンリポジトリばかりヒットするのクソだろ 謎クローンをやめろ

できることなら、より時間のかかるパッケージングの通知も取得したかったのですが、今回は心が折れました。知見のある方はコメントとかでご教示いただけるとめちゃくちゃ嬉しくなります...。

14
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?