---
title: プラグインによる効率的なエンジン拡張 - stelllaで実現するメタバース開発【UNREAL FEST 2023 TOKYO】
tags:  #ue4 #unreal fest #ue5 #ue-c++ #ue-editor #unreal fest 2023 tokyo  
author: [エピック ゲームズ ジャパン](https://www.docswell.com/user/EpicGamesJapan)
site: [Docswell](https://www.docswell.com/)
thumbnail: https://bcdn.docswell.com/page/9E2GG3ZQER.jpg?width=480
description: 講演アーカイブ： https://youtu.be/agU9FLvQsIo  講演内容： Unreal Engine のプラグイン機能を活用して、社内の技術資産を効率的に運用したり、プラグインからエンジン機能を拡張するためのノウハウを、弊社社内プラグインの stellla を題材にお話します。  講演者： 石川 陸(Alche株式会社) https://twitter.com/strvert 南舘 岳人(Alche株式会社) https://twitter.com/koituwasugee  Alche株式会社についてはこちら： https://alche.studio/  UNREAL FEST 2023 TOKYO 公式サイト： https://unrealengine.jp/unrealfest/2023/
published: June 02, 23
canonical: https://www.docswell.com/s/EpicGamesJapan/Z98W67-UE_UF23T_Alche
---
# Page. 1

![Page Image](https://bcdn.docswell.com/page/9E2GG3ZQER.jpg)

プラグインによる効率的なエンジン拡張
stelllaで実現するメタバース開発


# Page. 2

![Page Image](https://bcdn.docswell.com/page/D7YVV1RY7M.jpg)

はじめに
プラグインによるエンジン拡張をテーマとして、プラグインの開発ノウハウや、
管理・運用事例などについて話します。


# Page. 3

![Page Image](https://bcdn.docswell.com/page/VENMM2DRJ8.jpg)

本日の内容
●
●
●
●
●
●
登壇者・会社紹介
検証環境
UE におけるプラグイン
stellla 基本思想
プラグインによる拡張ノウハウ
プラグインの管理・運用事例


# Page. 4

![Page Image](https://bcdn.docswell.com/page/Y79NN1GZ73.jpg)

自己紹介
石川 陸
テックリード
●
高専を経て上京し、C/C++ を用いた組み込みシステムから Web
フロントまで幅広い開発に従事。学生の頃から Unreal Engine
を学んでおり、趣味が高じて Alche 株式会社に入社。
●
Alche 株式会社ではエンジニアチームのリードのほか、stellla
の設計や開発、開発ワークフロー・インフラの整備などを行っ
ている。
●
技術と創作が好き。
Riku Ishikawa
strvert
strvert
https://strv.dev


# Page. 5

![Page Image](https://bcdn.docswell.com/page/G78KK48YJD.jpg)

自己紹介
南舘 岳人
テクニカルアーティスト
●
CG会社でゲームエンジンを使った映像作品やゲーム開発を経験。
Unreal Engine を使った開発に魅了され、Alche 株式会社に入社。
●
現在はテクニカルアーティストとして stellla の開発をしている。
●
趣味で Unreal Engine のブログを投稿している。
●
インディーゲームと猫が好き。
Gakuto Minamidate
koituwasugee
ゲーム開発備忘録


# Page. 6

![Page Image](https://bcdn.docswell.com/page/L7LZZ6R9ER.jpg)

Alcheについて
Alcheは、メタバースという領域でエンターテイメント性
のあるコンテンツの制作、実装を行なっている。
建築、ランドスケープデザイナーやマジシャン、
シナリオライターなど多様なバックグランドをもった
メンバーで構成されている。
コンテンツを通して、勇気や元気を与えられるような
作品を発信する会社。
alche_studio
https://alche.studio/


# Page. 7

![Page Image](https://bcdn.docswell.com/page/4EMVV5RVEW.jpg)

実績(一例)
RADWIMPS SHIN SEKAI
お台場
バーチャル冒険アイランド
えんとつ町のプペルVR
Virtual Tokyo Tower
OFFICEtainment


# Page. 8

![Page Image](https://bcdn.docswell.com/page/PER223RW79.jpg)

メタバース領域の特徴と開発の経緯
●
メタバースという領域は、まだまだ発展途上であり未成熟なところが多い。
● ゲーム系のコンテンツと比較すると以下のような特徴がある。
○
開発プロジェクトとしても納期やリリースまでが短い。
○
一方で、要求される機能に共通点も多く、マルチプレイや、
アバターカスタマイズ、コミュニケーション といったものがある。
こうした状況を受けて弊社では、メタバース系コンテンツに頻出の機能を
プラグインとして集約した stellla を Unreal Engine を用いて開発している。
※これらはあくまで私達の考えです。


# Page. 9

![Page Image](https://bcdn.docswell.com/page/P7XDD4RVJX.jpg)

本講演での stellla の扱い
本講演では、Unreal Engine のプラグインについて説明しつつ、
実装事例として stellla の機能に触れる。
本来、stellla はマルチプレイ機能やバックエンド実装までを含む広範な
フレームワークだが、題材の都合上、今回は特に Unreal Engine プラグインとしての
stellla に注目した内容。


# Page. 10

![Page Image](https://bcdn.docswell.com/page/37KXXZR5JD.jpg)

検証環境
以下の環境を前提として検証を行っています。
●
Unreal Engine 5.1 (Launcher 版)
●
C++ 17


# Page. 11

![Page Image](https://bcdn.docswell.com/page/LJ355D8175.jpg)

Unreal Engine におけるプラグイン


# Page. 12

![Page Image](https://bcdn.docswell.com/page/8JDDDPMKJG.jpg)

Unreal Engine のプラグインの概要
●
コードとアセット、データなどのコレクション。
●
携帯性が良く、チームで簡単に共有できる。
●
簡単に ON / OFF できる。
●
約500 のビルトインプラグインが含まれているほか、
マーケットプレイスや GitHub などから追加で入手する
こともできる。
●
もちろん自分で実装することもできる。


# Page. 13

![Page Image](https://bcdn.docswell.com/page/VEPXXNR3J8.jpg)

Unreal Engine はモジュールの集合体
UE はモジュールの集合として実装されている。 Unreal Engine
モジュールは主にC++の実装からなり、大きく
Engine
ふたつのグループに分かれている。
Engine Module
● エディタやランタイム機能などからなる、
Unreal Engine そのものを形成する
モジュール。
Project
Module
Module
Module
Module
Module
Project Module
● C++ プロジェクトが作成されたときに、新
たに加わる独自のモジュール。
どちらも任意の数のモジュールを持てる。


# Page. 14

![Page Image](https://bcdn.docswell.com/page/27VLLKRNEQ.jpg)

プラグインはモジュールの運び屋
モジュールの視点で見ると、プラグインは
モジュールの運び屋。
プラグインは内部に独自のモジュールを
持つことが可能。
エンジンにもプロジェクトにも追加できる。
エンジンモジュールもプロジェクト
モジュールも、可能なことは大きくは
変わらず、どちらのプラグインからでも機能
を拡張していける。
Unreal Engine
Engine
Project
Module
Module
Module
Module
Module
Plugin A
Module
Plugin B
Module
Module
プラグインによってモジュールを追加できる。


# Page. 15

![Page Image](https://bcdn.docswell.com/page/5JGXXQM57L.jpg)

いつ有効なモジュールか？
モジュールがどこにあるかによって、
いつ有効になるものであるかが変わる。
Engine
Unreal Engine を利用しているときには常に
有効。(Editor / Runtime の差異はある)
Unreal Engine
Engine
Project
Module
Module
Module
Module
Module
Project
そのプロジェクトの中でだけ常に有効。
Plugin (Engine/Project 共通)
プラグインが配置、有効化されているときに
だけ有効。必要に応じてプロジェクトや
エンジンに機能を追加したり、
別プロジェクトに持ち運べる！
Plugin A
Module
無効化
Plugin B
Module
Module
ロードされるのは有効なプラグインのモジュールだけ。


# Page. 16

![Page Image](https://bcdn.docswell.com/page/47Q88KRLEP.jpg)

エンジンプラグインのオーバーライド
エンジンのビルトインプラグインは、
エンジンの拡張ポイントとしても機能する。
Unreal Engine
Engine
エンジン機能には、ビルトインのプラグイン
として実現されているものも多い。
エンジン側のプラグインと同名のプラグインが
プロジェクト側に存在する場合、プロジェクト
のプラグインが優先される。
プラグインとして実装されているエンジン機能
であれば、プロジェクトでカスタマイズ可能！
Project
Module
Module
Module
Module
Module
Plugin A
プロジェクト
Module
で上書き
Plugin A
Module
Module
エンジンのプラグインはプロジェクトで上書きできる。


# Page. 17

![Page Image](https://bcdn.docswell.com/page/KE422P8571.jpg)

プラグインはモジュール以外も持てる
エンジンやプロジェクトがコンテンツや設定
などを保持できるのと同様に、プラグインも
それらを保持できる。
Content : *.uasset, *.pak 等アセット
Conﬁg : *.ini 設定ファイル
Shaders : *.usf, *.ush シェーダー
Unreal Engine (のコンテンツ)
Engine Contents
Project Contents
Content
Content
Conﬁg
Conﬁg
Shaders
Plugin A
これらリソースも、プラグインに含めた場合は
プラグインの有効状態と連動する。
Plugin B
Conﬁg
Content
Content
Shaders
プラグインによってモジュールを追加
※プラグインとプロジェクトが持てるのはグローバルシェーダだけ


# Page. 18

![Page Image](https://bcdn.docswell.com/page/L71MM922JG.jpg)

つまり、プラグインは何ができる？
●
プロジェクトの実装で可能なことは、プラグインでもほぼすべてできる。
○ 多くの場合、再利用したいプロジェクト実装を整理してプラグインの
モジュールに移動するだけでプラグイン化できる。
●
再利用できるのは実装だけではなく、アセットや設定なども含まれる。
●
エンジン改造に手を付ける前に、プラグインで取れる手段は多い。
●
エンジンやエンジンプラグインのソースコードが公開されているので透明性が
高く、独自プラグイン実装に大いに参考にできる。


# Page. 19

![Page Image](https://bcdn.docswell.com/page/G7W33QR272.jpg)

逆に、プラグインは何ができない？
●
●
エンジンが直接持つモジュールに書かれたコードに割り込んだり、エンジン
モジュールを上書きするのは原則できない。この場合はエンジン改造が必要。
○
外から処理を追加できるように、デリゲートなどの拡張ポイントが
公開されていることはある。
○
利用するモジュールやクラスをモジュール名指定で設定可能になっている
場合もある。
エンジンおよび、エンジンに導入したプラグインのモジュールが、
プロジェクトや、プロジェクトのプラグインのモジュールに依存することは
できない。


# Page. 20

![Page Image](https://bcdn.docswell.com/page/4JZVVWR473.jpg)

そもそも、なぜエンジン改造を避けるのか？
●
エンジンへの変更を保守管理できるリソースがあるなら避ける必要はない。
● それにはどんなリソースが必要？
○
エンジンのコードをまるごとバージョン管理しなければいけなくなる。
○
コードを変更するために、チーム全体へエンジンの共有を行う必要がある。
○
ビルド時間の増大。
○
エンジンに更新があるたびに、変更を Merge する必要がある。
●
拡張した機能や実装を外部へと共有することが難しくなるという問題もある。
●
弊社では、必要性が無い限りはプラグインなどで対応するようにしている。
●
エンジン改造を行った場合には、Installed Build などが便利。
※これらはあくまで私達の考えです。


# Page. 21

![Page Image](https://bcdn.docswell.com/page/YE655GRGJV.jpg)

UEプラグインはフレームワーク基盤として強力
弊社の stellla は、こうした Unreal Engine の特徴を背景に誕生した。
昨今のメタバース領域のサービスには共通した実装が多い。これらの実装を都度再実装
すると、資産になりにくく、プロジェクト独自の実装に割けるリソースも減ってしまう。
しかし、UEのアーキテクチャやプラグインシステムは、エンジンを特定の目的のために
強化することを積極的に可能にしてくれている。
Unreal Engine の強力な機能をベースとしつつ、プラグインとしてフレームワークを実装
することで、機能を再利用したり、独自にエディタを拡張したりすることが可能。
効率的に製品のクオリティを高めることができる。


# Page. 22

![Page Image](https://bcdn.docswell.com/page/GE5YYV8XE4.jpg)

stellla 基本思想


# Page. 23

![Page Image](https://bcdn.docswell.com/page/972GG3KQ7R.jpg)

stellla 基本思想 - 整理された機能と最小限の依存
基本プラグイン
マルチプレイ対応
モバイル対応
core
multiplay
mobile
便利機能
backend
utility
︙
認証＆データストア


# Page. 24

![Page Image](https://bcdn.docswell.com/page/DJYVV1NYJM.jpg)

stellla 基本思想 - 整理された機能と最小限の依存
stellla プラグイン群は
core に依存している。
utility
core
プロジェクト
mobile
backend
multiplay


# Page. 25

![Page Image](https://bcdn.docswell.com/page/V7NMM2XRE8.jpg)

stellla 基本思想 - 整理された機能と最小限の依存
モバイル向けに
提供する予定はない。
utility
core
プロジェクト
mobile
backend
multiplay


# Page. 26

![Page Image](https://bcdn.docswell.com/page/YJ9NN18ZJ3.jpg)

stellla 基本思想 - 整理された機能と最小限の依存
仕様が変わってマルチプレイに
対応しないといけない。
utility
core
プロジェクト
mobile
backend
multiplay


# Page. 27

![Page Image](https://bcdn.docswell.com/page/GJ8KK4ZYED.jpg)

stellla 基本思想 - 整理された機能と最小限の依存
パッケージングサイズの
削減に貢献。
utility
core
プロジェクト
mobile
backend
multiplay


# Page. 28

![Page Image](https://bcdn.docswell.com/page/LJLZZ6D97R.jpg)

stellla 基本思想 - PnP (Plug and play)
プラグインを有効にする。
stellla mobile
Settings


# Page. 29

![Page Image](https://bcdn.docswell.com/page/47MVV5PV7W.jpg)

stellla 基本思想 - PnP (Plug and play)
自動でセットアップが完了！
Settings
stellla mobile
Complated !!


# Page. 30

![Page Image](https://bcdn.docswell.com/page/P7R2231WJ9.jpg)

stellla 基本思想 - ベースクラス
stellla 統合のために多くの
ベースクラスが存在する。
stellla core
stellla により拡張された
ベースクラスをプロジェクトで継承する。
ACharacter
Engine
AStelllaCharacter
stellla
AProjectCharacter
Project
AStelllaCharacter
UStelllaAnimInstance
AStelllaGameplayAbility
︙
︙
簡単に stellla の機能を利用できる。


# Page. 31

![Page Image](https://bcdn.docswell.com/page/PJXDD4YVEX.jpg)

stellla 基本思想 - 実装のアセット・モジュール化
実装をアセットとして分離することで
組み合わせのみでベースが完成。
BP
機能をアセットとして配信も可能。


# Page. 32

![Page Image](https://bcdn.docswell.com/page/3JKXXZ35ED.jpg)

stellla 基本思想 - IDベースで管理されたアイテム
メッシュ
ID
[ XXXX-YYYY-ZZZZ ]
機能
IDで管理されたアイテムに
必要なアセットが紐づけられている。
設定


# Page. 33

![Page Image](https://bcdn.docswell.com/page/LE355DG1J5.jpg)

stellla 基本思想 - プロジェクト互換性
異なるプロジェクトでもstelllaに則れば、
マルチプレイやアイテムに互換性ができる。
プロジェクトA
プロジェクトB
マップ
マップ
BP
BP
エモート
エモート
メッシュ
メッシュ
stellla
stellla


# Page. 34

![Page Image](https://bcdn.docswell.com/page/8EDDDP1KEG.jpg)

stellla 基本思想 - プロジェクト互換性
プロジェクトの垣根を超えたメタバース世界を目指している。
プロジェクトA
プロジェクトB
stellla


# Page. 35

![Page Image](https://bcdn.docswell.com/page/V7PXXNQ3E8.jpg)

stellla 基本思想 - まとめ
●
stellla は、実装のアセット化とモジュラー化や、それらの管理を行う機能をベースに
構築されており、迅速なシステムの構築と拡張が可能。
●
セットアップコストを抑えるとともに、stellla のワークフローを支援する
エディタ拡張も搭載している。また、あくまで Unreal Engine のプラグインなので、
Unreal Engine 自体の機能をそのまま活用した自由なコンテンツ制作を提供する。
●
最終的には、複数の世界を接続するシステムとして機能することを目的としている。
○
●
現時点でも、プロジェクト間で実行時にアイテムやブループリント実装を
共有する機能などを実現。
特定のアプリケーションやプラットフォームごとに閉じがちな、既存のメタバース系
サービスとは異なり、 stellla は「共通基盤」や「プロトコル」のようなものを
目指している。


# Page. 36

![Page Image](https://bcdn.docswell.com/page/2JVLLK5N7Q.jpg)

プラグインによる拡張ノウハウ


# Page. 37

![Page Image](https://bcdn.docswell.com/page/5EGXXQ65JL.jpg)

プラグインによる拡張ノウハウ
●
プラグイン開発を通して得られたノウハウや、
利用できる Unreal Engine の機能などを紹介。
●
特にプラグイン開発で便利な手法をピックアップして、
stellla の事例とともに 逆引き的に紹介 する。
○ プラグイン以外でも可能なことも含む。
●
stellla での独自機能はタイトルに 「 stellla での拡張 」と記述している。
●
は難易度。


# Page. 38

![Page Image](https://bcdn.docswell.com/page/4JQ88K4L7P.jpg)

プラグインによる拡張ノウハウ
- エディタ編 -


# Page. 39

![Page Image](https://bcdn.docswell.com/page/K7422PQ5J1.jpg)

Blueprint クラス選択一覧をカスタマイズしたい
プラグインに独自のベースクラス
などが増えてくると、独自クラスを
継承して実装を進めてほしくなる。
作成メニューの一覧を独自クラスに
書き換えてしまえば効果的に利用を
促せるし、クラスを検索して探す手
間も省ける。
クラス選択を独自クラスで上書き。
この例では Stellla のクラスが表示されている。


# Page. 40

![Page Image](https://bcdn.docswell.com/page/LJ1MM9P2EG.jpg)

→ Editor.ini で設定を追加 or 上書きする方法
プロジェクトやプラグインの Editor 系設定で、NewAssetDefaultClasses の
項目を変更するだけで書き換えることができる。
下に示したコードの ! から始まる行を消せば、上書きではなく追加もできる。
[/Script/UnrealEd.UnrealEdOptions]
!NewAssetDefaultClasses=ClearArray
+NewAssetDefaultClasses=(ClassName=&quot;/Script/Engine.Actor&quot;, AssetClass=&quot;/Script/Engine.Blueprint&quot;)
+NewAssetDefaultClasses=(ClassName=&quot;/Script/Engine.Character&quot;, AssetClass=&quot;/Script/Engine.Blueprint&quot;)
+NewAssetDefaultClasses=(ClassName=&quot;/Script/Engine.AnimInstance&quot;, AssetClass=&quot;/Script/Engine.Blueprint&quot;)
ClassName は /Script/[ModuleName].[ClassName] の形式。


# Page. 41

![Page Image](https://bcdn.docswell.com/page/GJW33Q22J2.jpg)

→ 専用のデリゲートをバインドして上書きする方法
UUnrealEdOptions::OnGetNewAssetDefaultClasses() に表示したいクラスの
リストを返す処理をバインドしておくことで、動的にクラスリストの内容を制御
できる。
このデリゲートにバインドすると、先ほどの Editor.ini のプロパティは無視される。
const static TArray&lt;FClassPickerDefaults&gt; ClassPickerDefaults
{
{TEXT(&quot;/Script/Engine.Actor&quot;), TEXT(&quot;/Script/Engine.Blueprint&quot;)},
{TEXT(&quot;/Script/GameplayAbilities.GameplayEffect&quot;), TEXT(&quot;/Script/Engine.Blueprint&quot;)},
};
if (UUnrealEdOptions* UnrealEdOptions = GUnrealEd-&gt;GetUnrealEdOptions())
{
UnrealEdOptions-&gt;OnGetNewAssetDefaultClasses().BindLambda([]() -&gt; const TArray&lt;FClassPickerDefaults&gt;&amp; {
return ClassPickerDefaults;
});
}
※ UnrealEdOptions はエンジン初期化後にしかアクセスできないことに注意。


# Page. 42

![Page Image](https://bcdn.docswell.com/page/4EZVVWD4J3.jpg)

エディタのツールバーやメニューを拡張したい
もとから存在するエディタのツールバーやメニューに
機能を増やしたくなることはよくある。
コンテキストメニューとか
ツールバーとか


# Page. 43

![Page Image](https://bcdn.docswell.com/page/Y7655G1GEV.jpg)

エディタのツールバーやメニューを拡張したい
stellla でも、エディタの各所に stellla での開発に便利な機能を拡張している。


# Page. 44

![Page Image](https://bcdn.docswell.com/page/G75YYV4X74.jpg)

→ ToolMenus で可能
BPでの実装を解説


# Page. 45

![Page Image](https://bcdn.docswell.com/page/9J2GG3VQJR.jpg)

→ ToolMenus - BPでの実装手順紹介
1. Editor Utility Blueprint を作成し、
EditrUtilityToolMenuEntry を継承。
2. BP の Class Defaults で最低限以下を設定する。
a.
b.
c.
d.
Menu: 拡張先のメニュー名。Edit Menuで確認できるもの。
Section: 追加にあたって作成するセクションの名前。
Name: 追加する Entry 自体の名前。
Entry Type: 拡張先のメニューのタイプに合ったものを選択する。
その他、ツールチップを定義したり、StyleSet を指定して
アイコンを設定することも可能。


# Page. 46

![Page Image](https://bcdn.docswell.com/page/DEYVV13YEM.jpg)

→ ToolMenus - BPでの実装手順紹介
3. “Run” という名前の CustomEvent を作成し、
Register Menu Entry を接続。
4.
Context Menu から Run !
EUB は “Run” という関数名で実行をハンドリングしている。
名前を合わせるだけで実行に反応できる。
5.
メニューが現れる。


# Page. 47

![Page Image](https://bcdn.docswell.com/page/VJNMM2VR78.jpg)

→ ToolMenus - 動作の設定
作成した Blueprint で関数をオーバーライドすることで、クリック時の処理を Blueprint で
書いたり、表示を動的に変更したり、有効無効を切り替えたりできる。意外なほどに簡単。


# Page. 48

![Page Image](https://bcdn.docswell.com/page/YE9NN16ZE3.jpg)

→ ToolMenus - 拡張先メニュー名の取得
拡張先のメニュー名の取得には、エディタで ToolMenus.Edit 1 コマンドを実行
すると、拡張可能な場所に Edit Menu ボタンが表示されるようになる。
ToolMenus.Edit 1


# Page. 49

![Page Image](https://bcdn.docswell.com/page/GE8KK4PY7D.jpg)

→ ToolMenus - 拡張先メニュー名の取得
表示されたボタンを押すと、UToolMenus で管理された
拡張可能メニューの詳細情報ウィンドウが表示される。
この情報を元に、好きな場所のメニューを拡張できる。
該当部のメニュー名
エントリのプロパティ
既にセクションにあるエントリ一覧


# Page. 50

![Page Image](https://bcdn.docswell.com/page/LELZZ619JR.jpg)

→ ToolMenus - Appendix
エディタで有効になっているアイコンとして利用可能な Style の一覧を得るには、
以下のようにすることができる。
また、Widget Reﬂector から開ける Texture Atlas Visualizer でも部分的に確認
可能。( StyleSetNameはわからない )
C++ ですべての Style を表示することで確認可能。
FSlateStyleRegistry::IterateAllStyles([](const ISlateStyle&amp; Style)
{
for (const FName&amp; StyleKey : Style.GetStyleKeys())
{
UE_LOG(LogTemp, Log, TEXT(&quot;StyleSet: %s\t\t StyleKey: %s&quot;),
*Style.GetStyleSetName().ToString(), *StyleKey.ToString());
}
return true;
});
すべての Style をログ出力。
Visualizer


# Page. 51

![Page Image](https://bcdn.docswell.com/page/4JMVV5WVJW.jpg)

→ ToolMenus - C++
もちろん C++ でも同様の仕組みで可能。
C++ なら、Slate (UE の UI システム) の資産をフルに
活用して更に自由にメニューをカスタマイズできる。
機能の複雑度や、使い捨て機能かどうかで使い分ける。
UToolMenu* Menu = UToolMenus::Get()-&gt;ExtendMenu(&quot;ContentBrowser.AddNewContextMenu&quot;);
FToolMenuSection&amp; Section = Menu-&gt;FindOrAddSection(&quot;ColorPickers&quot;);
Section.AddEntry(FToolMenuEntry::InitWidget(&quot;ColorPickerMenu&quot;, SNew(SColorPicker), FText::GetEmpty()));
これも案外シンプル。
C++ ならアセット作成メニューに
カラーピッカーを！(特に意味はない)


# Page. 52

![Page Image](https://bcdn.docswell.com/page/PJR223YWE9.jpg)

→ stellla での拡張
stellla では、C++ で Editor Utility Blueprint を更に拡張している。
特定ディレクトリの下に配置しておくだけでエディタ起動時に自動登録され、
登録のノードを配置する必要もなくなるなど、ツール開発支援機能も実装している。
プラグインを下支えとして気軽な拡張を可能にすることで、プロジェクト固有の
アドホックな拡張などもしやすくなる。拡張ツールを作成する人員の敷居も下げられる。
stellla では stellla 系プラグインか導入プロジェクトの
[Content]/Editor/ToolMenus に配置するだけ。


# Page. 53

![Page Image](https://bcdn.docswell.com/page/PEXDD4GV7X.jpg)

プラグインによる拡張ノウハウ
- ランタイム編 -


# Page. 54

![Page Image](https://bcdn.docswell.com/page/3EKXXZ457D.jpg)

プロジェクト/エディタ設定でプラグインの設定をしたい
Project Settings / Editor Preference を拡張できると、プラグイン機能のもつパラメータ
をプロジェクトごとに変更したり、アセットをプラグインに認識させたりできる。


# Page. 55

![Page Image](https://bcdn.docswell.com/page/L7355DL1E5.jpg)

→ DeveloperSettings を使うのがおすすめ
UDeveloperSettings を継承したクラスを含むモジュールがロードされると、
自動でエンジンが認識し、UPROPERTY を設定画面に表示してくれる。
UCLASS(Config=Game, DefaultConfig, DisplayName=&quot;Example Project Settings&quot;)
class UExampleProjectSettings : public UDeveloperSettings
{
GENERATED_BODY()
public:
UPROPERTY(Config, EditAnywhere, Category=&quot;Example&quot;)
FString ExampleString;
UPROPERTY(Config, EditAnywhere, Category=&quot;Example&quot;)
int32 ExampleInt;
UPROPERTY(Config, EditAnywhere, Category=&quot;Example&quot;)
TSoftObjectPtr&lt;UStaticMesh&gt; ExampleStaticMeshObject;
};
これを定義するだけで実装完了！


# Page. 56

![Page Image](https://bcdn.docswell.com/page/87DDDPNK7G.jpg)

→ DeveloperSettings を使うのがおすすめ
設定した値は、作成したクラスに対して自動生成される CDO (Class Default Object) の
値として利用される。以下のようにどこからでもアクセスできる。
const UExampleProjectSettings* Settings = GetDefault&lt;UExampleProjectSettings&gt;();
Settings-&gt;ExampleInt;
Settings-&gt;ExampleString;
Settings-&gt;ExampleStaticMeshObject;
Blueprint から利用する際には、取得を行う UFUNCTION を作成すれば OK。
UFUNCTION(BlueprintCallable, Category=&quot;ExampleProjectSettings&quot;)
static const FString&amp; GetExampleStringValue()
{
const UExampleProjectSettings* Settings = GetDefault&lt;UExampleProjectSettings&gt;();
return Settings-&gt;ExampleString;
}


# Page. 57

![Page Image](https://bcdn.docswell.com/page/VJPXXN5378.jpg)

設定ファイルとカテゴリについて
UCLASS(Config= ) の値 (= Conﬁg名) を変えることで、保存する設定ファイルや、
エディタ上での設定の表示場所が変わる。
ゲーム機能に関する設定なのか、エディタ機能に関する設定なのか、
個人の環境設定なのか、などによって使い分ける。
主要な Conﬁg 名の例
Conﬁg名
設定ファイル
エディタ表示場所
Game
*Game.ini
ProjectSettings
Engine
*Engine.ini
ProjectSettings
Editor
*Editor.ini
ProjectSettings
EditorPerProjectUserSettings *EditorPerProjectUserSettings.ini EditorPreferences
※「*」 付きなのは、配置場所によってプレフィックスが変動するため。


# Page. 58

![Page Image](https://bcdn.docswell.com/page/2EVLLKPNJQ.jpg)

プラグイン独自の設定ファイルが利用できる
プラグインのモジュール内でのみ、プラグインの名前を冠した Conﬁg 名を利用すると、
専用の設定ファイルを読み込める。もしプラグイン名が ExamplePlugin なら、以下のような形。
UCLASS(Config = ExamplePlugin, DefaultConfig,
DisplayName=&quot;Plugin Unique Settings&quot;)
class UPluginUniqueSettings : public UDeveloperSettings
{
GENERATED_BODY()
// 略
};
プラグインの設定ファイルを分離することで、
設定の所属の明確化を図れたり、設定ファイルの
肥大化を防いだりすることができる。
プロジェクトで値を上書きすることも可能。
ExamplePlugin
Conﬁg
BaseExamplePlugin.ini
[Project Folder]
Conﬁg
DefaultExamplePlugin.ini
プラグインとプロジェクト、どちらの
Conﬁg でも利用できる。


# Page. 59

![Page Image](https://bcdn.docswell.com/page/57GXXQP5EL.jpg)

プラグイン有効化で設定を上書きする方法
プラグインのフォルダ内に対応する Conﬁg 名の設定ファイルを配置するだけ！
プラグイン初期化時に検出され、設定を上書きする。
ただし、EditorPerProjectUserSettings
はプラグインで上書きできない Conﬁg 名として
処理されており配置しても無意味。
[Plugin Folder]
Source
Conﬁg
Game.ini
有効化と同時に行いたい設定を記述可能なため、
プラグイン利用時の設定系セットアップを簡易化できる。
Editor.ini
Engine.ini
※「プラグインで上書きできない Conﬁg名」 を自分で追加する方法もある。


# Page. 60

![Page Image](https://bcdn.docswell.com/page/4EQ88K2LJP.jpg)

キャラクターなどの実装を機能別に分離・整理したい
Unreal Engine で愚直に実装を始めると、キャラクターなどの基本的なクラス
の BP 実装が爆発しがち。


# Page. 61

![Page Image](https://bcdn.docswell.com/page/KJ422PL5E1.jpg)

キャラクターなどの実装を機能別に分離・整理したい
なぜキャラクタークラスは爆発するのか？
●
入力などのイベントハンドリングをグラフに配置できる。
●
キャラクターにあらゆる関するロジックが配置されやすい。
1つのキャラクタークラス内に、「入力などのハンドリング」と「キャラクターの
ロジック」がベタ書きされることで、プロジェクト間はおろか、プロジェクト内
ですら再利用が難しい状態を生み出している事が多い。
→ 入力などのハンドリングとキャラクターロジック をキャラクターから分離できれば
解決する。


# Page. 62

![Page Image](https://bcdn.docswell.com/page/LE1MM9L27G.jpg)

→ ひとつなぎのキャラクター
Character
Event
Logic
キャラクターアセット
キャラクターにあらゆる実装を書いている。
こうしたキャラクターはよく爆発している。


# Page. 63

![Page Image](https://bcdn.docswell.com/page/GEW33QV2E2.jpg)

→ GameplayAbility や Enhanced Input の活用
Enhanced Input
Gameplay Ability
● 入力イベントを抽象化した InputAction。
● 具体的な入力とアクションを紐付ける
InputMappingContext。
● BP のロジックを、
1 ロジック 1 アセットで扱える Ability。
● Ability の処理は任意の方法で Activate
することで実行可能。
などの機能を利用して入力の定義や
ハンドリングを分離できる機能。定義は
すべてデータアセットとして管理される。
UE 5.1 から標準の入力システムに。
実行可能なロジックを Ability アセットとして
扱うことが可能。
キャラクターなどに Ability を付与すると、
その上でロジックを実行できる。
Unreal Engine のアセットベースな強力な機能が活用できる


# Page. 64

![Page Image](https://bcdn.docswell.com/page/47ZVVW44E3.jpg)

→ GameplayAbility や Enhanced Input の活用
トリガ
(Event)
Ability
(Logic)
入力
アセット
ロジック
アセット
EnhancedInput
付与
実行
Character
キャラクター
アセット
Enhanced Input と Gameplay Ability を連携させる実装と、
Ability を受け取れるキャラクターを実装した場合。


# Page. 65

![Page Image](https://bcdn.docswell.com/page/YJ655G3G7V.jpg)

→ GameplayAbility や Enhanced Input の活用
トリガ
付与
実行
アセット単位で再利用性が高まることで、組み合わせ的に実装が可能に。


# Page. 66

![Page Image](https://bcdn.docswell.com/page/GJ5YYVLXJ4.jpg)

→ プラグインのコンテンツとしてアセットを持てる
Plugin
Project A
Project B
Project C
こうした再利用性の高いアセットをプラグインで運搬することで、
プロジェクトの実装を効率化する。


# Page. 67

![Page Image](https://bcdn.docswell.com/page/LE355DL4J5.jpg)

→ stellla での拡張
● stellla には、予め UE の Enhanced Input や Ability System を拡張し、
組み合わせベースで、コード(ノード)を書かずに連携させる事ができる仕組み
が実装されている。
●
それらによって駆動されることを前提とした便利機能を実装した、stellla専用
の Character / Actor などの基本クラスを含めており、プロジェクトでは
これらを継承することですぐに、既存資産の利用を開始できる。
→ 過去に実装した機能アセットを簡単に組み合わせることができるので、
コンテンツを迅速に構築できる。新たな機能を追加する時も、Ability を実装して、
付与の設定を行うだけ。作った Ability は新たな資産となる。


# Page. 68

![Page Image](https://bcdn.docswell.com/page/8EDDDPN5EG.jpg)

→ stellla での拡張 - キャラクター機能実装例
Project
AProjectCharacter
stellla の基本クラス
を継承
stellla Plugin
AStelllaCharacter
アセットと設定による
機能実装
プロジェクト独自
Ability
stellla 同梱
Ability
stellla が更に再利用性と実装の簡便性を向上


# Page. 69

![Page Image](https://bcdn.docswell.com/page/V7PXXN5DE8.jpg)

→ stellla での拡張 - Abilityの拡張例
Ability を拡張し、Enhanced Input によって Activate できるように接続しているほか、
Ability 内で InputAction の値や情報にアクセスできる機能なども追加。


# Page. 70

![Page Image](https://bcdn.docswell.com/page/2JVLLKPG7Q.jpg)

→ stellla での拡張 - 機能のランタイムインストール
実装のアセットによる分離のメリットは実機でのランタイムにもある。
アセットになることで、C++実装などと異なり、ランタイムにも機能を
個別のファイルとして扱いやすくなる。
stellla では、このメリットを活かして、単体 Ability のパッケージングと配布や、
クライアントがランタイムに単体の Ability をダウンロードし、その場で
キャラクターに新機能を追加することなどを可能にしている。
※ C++実装をキャラクター機能単位で動的リンクライブラリにして配ったりするのはかなり大変


# Page. 71

![Page Image](https://bcdn.docswell.com/page/5EGXXQQDJL.jpg)

プラグインの管理・運用事例


# Page. 72

![Page Image](https://bcdn.docswell.com/page/4JQ88KKX7P.jpg)

バージョン管理
●
バージョン管理には Git を利用
○
●
バイナリを扱うために Git LFS を活用
○
●
ブランチを用いたワークフローや、周辺ツールとの連携性の良さ、コストなどが選定理由。
Git でバイナリなどの大きなファイルを効率的に管理するための拡張。
オープンソースのセルフホストGitサービスの Gitea を利用
○
○
○
Git LFS の Lock にも対応している。
オンプレミスで安価に運用可能。
LFSファイルの実体を AWS S3 などのバケットに配置でき、
コストを抑えつつ高速転送 が可能。


# Page. 73

![Page Image](https://bcdn.docswell.com/page/K7422PP2J1.jpg)

プラグイン管理に特有の課題
●
再利用を目的とした、複数のプロジェクトに導入されるプラグインの開発は
どこで行う？ どうやってバージョン管理する？
●
特定のプロジェクトに依存しない形でのCI(ビルドチェック)はどうする？
プロジェクトに依存せずに、プラグイン単体で品質を管理する必要がある。
などなど……


# Page. 74

![Page Image](https://bcdn.docswell.com/page/LJ1MM99KEG.jpg)

プラグイン管理に特有の課題
●
再利用を目的とした、複数のプロジェクトに導入されるプラグインの開発は
どこで行う？ どうやってバージョン管理する？
●
特定のプロジェクトに依存しない形でのCI(ビルドチェック)はどうする？
プロジェクトに依存せずに、プラグイン単体で品質を管理する必要がある。


# Page. 75

![Page Image](https://bcdn.docswell.com/page/GJW33QQPJ2.jpg)

良くなかった例 ➀
各プロジェクトのリポジトリ内部に、
直接プラグインのファイルを配置して運用する。
プロジェクトA リポジトリ
プロジェクトB リポジトリ
プラグインX
プラグインX
File
File
File
File


# Page. 76

![Page Image](https://bcdn.docswell.com/page/4EZVVWW6J3.jpg)

良くなかった例 ➀
直感的だが、プロジェクトの履歴と混在し、
プラグイン自体のバージョン管理ができていない。
また、手動でコピペする以外にプラグインを導入・管理する方法がない。
プロジェクトA リポジトリ
プロジェクトB リポジトリ
プロジェクトC リポジトリ
プラグインX
プラグインX
プラグインX
File
File
File
File
？？？
File
File


# Page. 77

![Page Image](https://bcdn.docswell.com/page/Y7655GGLEV.jpg)

良くなかった例 ②
プラグイン単独のリポジトリを作成してバージョン管理。
必要なバージョンをプロジェクトにコピー。
プロジェクト リポジトリ
プラグインX リポジトリ
プラグインX
Commit
File
File
手動で導入
File
File
※ Commit とは Git における変更履歴のこと


# Page. 78

![Page Image](https://bcdn.docswell.com/page/G75YYVVM74.jpg)

良くなかった例 ②
プラグインの履歴は管理できるが、手動でコピペが必要なのは変わらず。
また、各プロジェクトに現在導入されているプラグインのバージョンなども
人間が管理する必要がある。
プロジェクト リポジトリ
プラグインX リポジトリ
プラグインX
Commit
File
File
File
File
今入ってるバージョンはいつのもの？
更新は気付いた時にコピペする？
※ Commit とは Git における変更履歴のこと


# Page. 79

![Page Image](https://bcdn.docswell.com/page/9J2GG33RJR.jpg)

→ Git Submoduleを使って解決
Git Submodule を活用し、
各プロジェクトはプラグインリポジトリの
特定コミットへの参照情報を管理している。
プロジェクト リポジトリ
プラグインX リポジトリ
Commit
Submodule
プラグインX
特定コミットの参照
File
File
※ Commit とは Git における変更履歴のこと


# Page. 80

![Page Image](https://bcdn.docswell.com/page/DEYVV115EM.jpg)

プラグイン管理に特有の課題
●
再利用を目的とした、複数のプロジェクトに導入されるプラグインの開発は
どこで行う？ どうやってバージョン管理する？
→ Git 管理の場合、 Git Submodule がプラグインにぴったり。
きちんと単体でバージョン管理し、手間や運用コストを削減できる。
●
特定のプロジェクトに依存しない形でのCI(ビルドチェック)はどうする？
プロジェクトに依存せずに、プラグイン単体で品質を管理する必要がある。


# Page. 81

![Page Image](https://bcdn.docswell.com/page/VJNMM22478.jpg)

プラグイン管理に特有の課題
●
再利用を目的とした、複数のプロジェクトに導入されるプラグインの開発は
どこで行う？ どうやってバージョン管理する？
→ Git 管理の場合、 Git Submodule がプラグインにぴったり。
きちんと単体でバージョン管理し、手間や運用コストを削減できる。
●
特定のプロジェクトに依存しない形でのCI(ビルドチェック)はどうする？
プロジェクトに依存せずに、プラグイン単体で品質を管理する必要がある。


# Page. 82

![Page Image](https://bcdn.docswell.com/page/YE9NN114E3.jpg)

プラグインのビルドチェック
●
UE には、プラグインの単体パッケージング機能がある。
これは UAT (Unreal Automation Tool) を通じて CLI で実行できる。
●
複数のビルド対象プラットフォームと、エディタプラットフォームを指定できる。
RunUAT.bat BuildPlugin
-Plugin=&quot;[プラグインのパス ]/StelllaCore.uplugin&quot;
-Package=&quot;[パッケージ済み出力ディレクトリ ]&quot;
-EngineDir=&quot;[ビルドに利用するエンジンのインストールディレクトリ ]&quot;
-TargetPlatforms=&quot;[Win64+Android+IOS のようにターゲットのプラットフォームを +で接続して指定 ]&quot;


# Page. 83

![Page Image](https://bcdn.docswell.com/page/GE8KK44V7D.jpg)

ビルドに含めるパスを設定する
パッケージング時、成果物として、
プラグインフォルダから追加でファイルを
コピーしたい場合がある。
[FilterPlugin]
この場合、 FilterPlugin.ini を配置すれば、
BuildPlugin コマンドが自動でコピーを行う。
/README.txt
/Extras/...
/Binaries/ThirdParty/*.dll
[Plugin]/Conﬁg/FilterPlugin.ini
ドキュメントや動的ロードするライブラリを含
める作業を自動化できる。
再帰やワイルドカードも利用できる。


# Page. 84

![Page Image](https://bcdn.docswell.com/page/LELZZ66RJR.jpg)

Gitea Actions による CI
CIを設定した
プラグインリポジトリ
PR
merge
ビルド実行イベント
ステータスをチェック
ビルドマシン
Windows
Mac
弊社では、Gitea Actions という CI 機能を利用して自動で
マルチプラットフォームに単体パッケージを行っている。
Linux
main


# Page. 85

![Page Image](https://bcdn.docswell.com/page/4JMVV55PJW.jpg)

プラグイン管理に特有の課題
●
再利用を目的とした、複数のプロジェクトに導入されるプラグインの開発は
どこで行う？ どうやってバージョン管理する？
→ Git 管理の場合、 Git Submodule がプラグインにぴったり。
きちんと単体でバージョン管理し、手間や運用コストを削減できる。
●
特定のプロジェクトに依存しない形でのCI(ビルドチェック)はどうする？
プロジェクトに依存せずに、プラグイン単体で品質を管理する必要がある。
→ UAT で単体パッケージング。CLI ツールであるため、CIシステムと
連携して自動化することも可能。


# Page. 86

![Page Image](https://bcdn.docswell.com/page/PJR2233YE9.jpg)

おわりに


# Page. 87

![Page Image](https://bcdn.docswell.com/page/PEXDD4447X.jpg)

おわりに
●
Unreal Engine は拡張性を意識した設計で構築されている。
拡張用のツールキットや拡張ポイントもエンジンに多数用意されているため、
プラグインからランタイム機能もエディタ機能も拡張していける。
●
stellla は、Unreal Engine のプラグインとして弊社が開発しているメタバース系
サービス構築に特化したフレームワーク。
Unreal Engine の拡張性と豊富な機能、オープンなソースコードに支えられて、
stellla のようなプラグインの開発も進めやすく、エンジンを存分に活用すること
ができる。
●
また、ワークフローの上でも、UAT などのユーティリティを利用することで、
プラグインの開発や運用の堅牢性を高めていくことができる。


# Page. 88

![Page Image](https://bcdn.docswell.com/page/3EKXXZZP7D.jpg)

ご清聴ありがとうございました


