Skip to main content
猫でも分かる UE4の新しいサンプル
「Action RPG」について
Epic Games Japan 岡田和也
第8回 UE4勉強会 in 大阪
自己紹介
Epic Games Japan サポートエンジニア
岡田 和也(おかず@pafuhana1213)
サポートエンジニアしてます
バ美肉が最近の趣味
本日のテーマにある「Action RPG」ってなに?
UE4.20リリースと同時に突然公開された新しいサンプル
○ https://www.unrealengine.com/marketplace/action-rpg
○ AppStore, GooglePlayでも配信中!もちろん無料!
色々な要素が詰まってる
良いサンプル!
色々ありすぎて
どこから手を付けたらいいのか
分からない…
● プレイヤー・敵キャラの制御
● コンボの実装
● AIを使ったオートプレイ
● AnimNotify
● 装備の切り替え
● HP, MPの管理
● ランドスケープ、フォリッジ
● 各UIの制御
● サウンド一括ON/OFF
● Sequencerによるカットシーン
● タイトル・リザルトを含む
一連のゲームループ
● セーブ・ロード処理
● Asset Managerを使った
アセット管理
● Gameplay Ability System
● モバイル対応を考慮した
最適化
● ローディングスクリーン
● BPとC++のバランス
などなど…
ということで、
この辺りは見たほうがいいよ!って所や
ここは是非解説したい!と思った所を話していきます
お品書き
見ることオススメ編
解説したい編
○ Action RPG Loading Screen Module
○ Asset Managerを使ったアセット管理
○ Game Ability System
○ BPとC++のバランスについて
見ることオススメ編
AnimMontageのSectionを使ったコンボ処理の実装
BP_PlayerCharacter
○ Do Melee Attack関数, Jump Section for Combo関数
疑似影 + CapsuleShadow
スケルトンの共有
プレイヤーキャラクタのスケルトンは
SK_Manequinと同じ
○ SK_Manqeuinの
アニメーションの流用が可能
○ アニメーション流用に関する
スライドへのリンク
Sequencerの活用例
ゲームメイン部分でのカットシーン
○ Shots, Subscenes
○ Pre Roll Frames
AIの実装サンプル
敵キャラとプレイヤーのAutoPlayで使用
○ Behavior Tree
背景のコリジョン
Blocking Volumeを使った簡易コリジョンで負荷削減!
擬似的なライティングを実現するマテリアル
ライトの向き、色などをパラメータで制御
○ MI_Aspen_Tree_Lit_Blowing
Landscape用マテリアルのサンプル
M_CaveLandscape_Inst
○ Layer Blendの使い方
○ ES2の制限を考慮した作り( Feature Level Switch )
AnimNotify, AnimNotifyState
アニメーションにイベント・音・エフェクトを追加
○ みんな大好きトレイルエフェクトやディゾルブ演出も
自作AnimNotify
キャラクタの制御・演出などを
AnimNotify内で実装
UI
ゲームを作る上でよく使うUIがたくさん
○ WB_Checkbox, WB_GenericButtonは
UserWidgetではなく既存のWidgetを継承してカスタムしている例
Sound Class, Sound Mixを用いた音の制御
音に関する様々な効果・制御を実現している!
○ スローモーション演出中はボイスを野太く
○ オプション画面から音の一括ON/OFF
無効化するプラグインの参考に
プラグインを無効化することでパッケージサイズを削減
○ ActionRPG.uprojectをテキストエディタで開くと
無効化したプラグインの一覧を簡単に確認可能
他にもエフェクト・マテリアルなどのアセットや
各BPにおける実装など、参考になる箇所がたくさん!
是非いろいろ見てみてください!
実際に触って改造したりすると理解が進むのでオススメ!
お品書き
見ることオススメ編
解説したい編
○ Action RPG Loading Screen Module
○ Asset Managerを使ったアセット管理
○ Game Ability System
○ BPとC++のバランスについて
Action RPG
Loading Screen Module
● 動画を用意
なぜ動くローディング画面を入れる必要があるのか?
○ 真っ暗な画面でもいいんじゃないの?
○ 動かない一枚絵でもいいんじゃ?
ユーザが受けるストレスが半端ない
○ 何が起こっているのか分からない…
正しい挙動なの?不具合なの?
ということで、
動くローディング画面を作る必要がある
○ 「ロード中であること」
「ちゃんと処理が走っていること」をユーザに伝える
動くローディング画面は少し面倒!
理由①
Open Levelを使うと
必ず ブロッキングロード処理 が走るため
○ ロード処理中、ゲーム内の処理・描画がストップするので、
ローディング画面の動きも止まる または 非常にカクつく
動くローディング画面は少し面倒!
理由②
事前にサブレベルをロードしていても
実際に表示する際に瞬間的な負荷が発生するため
○ 表示時に一瞬カクついてしまう
UE4におけるLoadingとGCのProfilingと最適化手法
https://www.slideshare.net/EpicGamesJapan/420-ue4loadinggcprofiling-108367408
それぞれロード時間・負荷を削減することは可能
しかし、0にすることは不可能
○ PCなら知覚できない程度まで負荷を調整できますが、
低スペックなモバイル端末では非常に難しい
Action RPGで用意されている
ローディング画面の仕組み
「Action RPG Loading Screen Module」
を使おう!
置いている場所はここ!
Action RPG Loading Screen Moduleの何がいいのか?
BP, C++によるゲーム処理(Game Thread )や
ローディング処理( I/Oなど ) の裏で動作してくれる!
○ Movie Playerの仕組みを利用
○ https://api.unrealengine.com/INT/API/Runtime/
MoviePlayer/index.html
裏で動作することによるメリット
1. ロード処理によりゲーム・エンジン処理が
ストップしても、ローディング画面の表示に影響しない
2. ローディング画面を表示・更新する処理負荷が
ロード処理に影響することを抑制できる!
※ 動作させる環境のスペックや構成に
ある程度左右はされる部分ではあります
各関数がActionRPGのどこで呼ばれているか
● Start Loading Screen関数
○ Load Game Level, Restart Game Levelで使用
● Stop Loading Screen関数
○ 各パーシスタントレベルのBegin Playで使用
ActionRPGLoadingScreen.cpp にて
virtual void StartInGameLoadingScreen(bool bPlayUntilStopped, float PlayTime)
override
{
FLoadingScreenAttributes LoadingScreen;
LoadingScreen.bAutoCompleteWhenLoadingCompletes = !bPlayUntilStopped;
LoadingScreen.bWaitForManualStop = bPlayUntilStopped;
LoadingScreen.bAllowEngineTick = bPlayUntilStopped;
LoadingScreen.MinimumLoadingScreenDisplayTime = PlayTime;
LoadingScreen.WidgetLoadingScreen = SNew(SRPGLoadingScreen);
GetMoviePlayer()->SetupLoadingScreen(LoadingScreen);
}
それぞれのフラグの内容(コメントを翻訳)
● bAutoCompleteWhenLoadingCompletes
○ trueの場合、ロードが完了すると
すぐにローディング画面が消えます
● bWaitForManualStop
○ trueの場合、動画の再生は
Stopが呼び出されるまで続きます
● bAllowEngineTick
○ trueの場合、ゲームスレッドがローディ
ング動画が終了するのを待っている間、
エンジンのTickを呼び出します。
これは起動後のロード画面でのみ機能し、
潜在的にunsafeです
● MinimumLoadingScreenDisplayTime
○ ローディング画面を開くための最小時間。
● WidgetLoadingScreen
○ 表示するWidgetの指定
大雑把な使い分け
明示的にStopを呼ぶまでローディング画面を続けたい
○ bAutoCompleteWhenLoadingCompletes = false;
○ bWaitForManualStop = ture;
ロードが完了したら自動的にローディング画面を終わらせたい
○ bAutoCompleteWhenLoadingCompletes = ture;
○ bWaitForManualStop = false;
○ (FLoadingScreenAttributes の初期設定はこっち)
表示する内容を変えたい場合
C++コードを少しいじる必要があります
○ SRPGLoadingScreenクラスのConstruct関数
(ActionRPGLoadingScreen.cpp)
画像のみを替えたい場合は、
アセットパスの部分を書き換える
static const FName LoadingScreenName(TEXT("/Game/UI/T_ActionRPG_TransparentLogo.T_ActionRPG_TransparentLogo"));
公式Wikiでの解説(英語)
○ https://wiki.unrealengine.com/Loading_Screen
Asset Managerを使った
アセット管理
Asset Managerとは?
アセットの非同期読み込み(裏読み)を
使用・管理するための機能
○ 公式ドキュメント「アセット管理」
以前はC++でのみ提供していました
○ Streamable Manager
○ 公式ドキュメント「アセットの非同期ロード」
サブレベルの事前ロードでも
同じことができるのでは…?
サブレベルの事前ロードとの大きな違い
アセット単位でのロード管理が可能
○ サブレベルの場合、
レベルに配置などして参照関係を作る必要がある
○ メモリ容量を考慮した厳密な調整・管理がしやすい
Asset Managerには便利機能がたくさん!
ロード対象のアセット群を抽出・管理するための
Primary Asset という概念
○ Primary Asset Label という作業支援用アセットも標準で用意
Asset Managerには便利機能がたくさん!
Asset Managerの管理対象を可視化するための
Asset Audit機能
○ Reference Viewer, SizeMapもより便利に
詳細はこちらで!
https://www.slideshare.net/Ep
icGamesJapan/ue4-95204920
https://www.slideshare.net/Ep
icGamesJapan/ue4-chunk-id
ひとまず、今知っておいて欲しいこと ①
Asset Manager は Primary Asset として
設定されたアセットを管理する
ひとまず、今知っておいて欲しいこと ②
Asset Managerを使って非同期ロードするには…?
ロード対象のアセットを…
○ Primary Assetにする
○ Primary Asset から参照されるようにする
( Secondary Asset )
Primary Assetとして設定するには…?
プロジェクト設定の Asset Managerで各項目を設定
○ Primary Asset Typeの名前
○ 対象アセットの クラス
○ 抽出対象のフォルダ
重要:Primary Assetとして指定する際の注意点!
指定するクラスには
GetPrimaryAssetId 関数を 必ず 用意する必要がある
○ デフォルトで用意されているのは
UWorldクラスと UPrimaryDataAssetクラスのみ
UworldにおけるGetPrimaryAssetId関数
FPrimaryAssetId UWorld::GetPrimaryAssetId() const
{
UPackage* Package = GetOutermost();
if (!Package->HasAnyPackageFlags(PKG_PlayInEditor))
{
// Return Map:/path/to/map
return FPrimaryAssetId(UAssetManager::MapType, Package->GetFName());
}
return FPrimaryAssetId();
}
GetPrimaryAssetId関数 を実装する上での注意
返り値 FPrimaryAssetId の 第1引数(FPrimaryAssetType)は
プロジェクト設定で指定する文字列と一致させる!
return FPrimaryAssetId(UAssetManager::MapType, Package->GetFName());
FName(TEXT("Map"));
少し脱線
Should Guess Type and Name in Editorが有効な場合、
エディタ上なら この関数がなくても一応動くが、
パッケージでは不具合発生するので注意
ややこしい…(;´∀`)
標準で PrimaryAssetとして登録されている
UWorld, UPrimaryAssetLabelが少し複雑かつ用途が特殊なので、
独自クラスをPrimary Assetにする際の参考にし辛いという点もつらい
Action RPGが
Asset Manager, Primary Assetの運用
に関する、良いサンプルになっています!
独自クラスをPrimary Assetとして管理
URPGItemクラス
○ UPrimaryDataAsset 継承
○ 武器・回復アイテムなどの
各パラメータや
使用するアセットを管理するアセット
FPrimaryAssetId URPGItem::GetPrimaryAssetId() const
{
return FPrimaryAssetId(ItemType, GetFName());
}
プロジェクト独自にAsset Manager
RPGAssetManager
○ 対象のPrimaryAssetを 同期 ロードする処理を追加
○ RPGItemの各派生クラスで使用するFPrimaryAssetTypeの定義
const FPrimaryAssetTypeURPGAssetManager::PotionItemType = TEXT("Potion");
const FPrimaryAssetTypeURPGAssetManager::SkillItemType = TEXT("Skill");
const FPrimaryAssetTypeURPGAssetManager::TokenItemType = TEXT("Token");
const FPrimaryAssetTypeURPGAssetManager::WeaponItemType = TEXT("Weapon");
プロジェクト独自のAsset Managerへの差し替え方法
DefaultEngine.ini にて 以下の文字列を追加
○ クラス名はプロジェクトに応じた名前に適宜変更
[/Script/Engine.Engine]
AssetManagerClassName=/Script/ActionRPG.RPGAssetManager
ゲーム中にどのようにして使われているか
BP_GameInstance の 初期化処理にて
各RPGItemを非同期ロード
ゲーム中にどのようにして使われているか
装備購入・入れ替え画面における
武器の説明・アイコン表示で使用
○ AddInventoryItemsToList イベント
ゲーム中にどのようにして使われているか
武器を切り替えた際の
GameAbilityの再設定処理
○ ARPGCharacterBase::FillSlottedAbilitySpecs関数 ( C++ )
このような管理にするメリット
データ管理しやすい
○ Structによるデータ管理は不便
○ データ管理用のBPをわざわざ用意するのは無駄が多い
このような管理にするメリット
Asset Managerの各機能が使える
○ 必要に応じて、必要最小限のアセット非同期ロード
(例:未取得の武器データはロードする必要はない)
○ Primary Assetに関する検索・フィルタ処理を使える
(同様の機能を自前で用意するのは大変)
ある程度の規模になってくると
Asset Managerによるアセット管理は
必須ともいっていい…かと…!
小規模なプロジェクトでも
十分恩恵受けられるので是非使ってみましょう!
Gameplay Ability System
Gameplay Ability Systemってなに?
● ゲームプレイアビリティシステムは、あなたがRPGやMOBAタイトルで見か
ける。能力や属性を構築するための高度に柔軟なフレームワークです。
● ゲーム内のキャラクターが使用するアクションやパッシブアビリティ、これ
らのアクションの結果としてさまざまな属性を作成または消耗させるステー
タスエフェクト、これらのアクションの使用を規制するための「クールダウ
ン」タイマーやリソースコストの実装、各レベルでの能力とその効果のレベ
ルを変更し、パーティクルやサウンドエフェクトなどをアクティブにします
● 簡単に言えば、このシステムは、現代RPGやMOBAのタイトルに設定された
キャラクターの能力と同じくらい単純なジャンプや複雑なゲーム能力の設計、
実装、効率化に役立ちます。
https://docs.unrealengine.com/en-us/Gameplay/GameplayAbilitySystem
Gameplay Ability Systemってなに?
キャラクタのステータス、武器の攻撃力、
スキルの効果などのデータ・挙動を
効率的に管理・実装するためのフレームワーク
Gameplay Ability Systemってなに?
主なメリット・特徴
○ データドリブンな設計
○ ネットワーク対応を考慮した作り
○ 処理を非同期に実行可能
○ 複数人での作業や量産に向いている
○ Fortnite, Paragonで実際に使われている
● Health
● Mana
● Damage
● MoveSpeed
Attribute Set
Ability System
Component
Attribute Set
Ability System
Component
回復アイテムをゲットする
イベントが発生
処理の流れのイメージ
Gameplay Ability System
Attribute Set
Ability System
Component
回復処理を行う
GamePlay Abilityを実行
処理の流れのイメージ
Gameplay Ability System
Attribute Set
Ability System
Component
Attribute Setが管理している
Health (体力Attribute)を変更するEffectを実行
Gameplay Effect
処理の流れのイメージ
Gameplay Ability System
Attribute Set
Ability System
Component
体力の変更通知をActorに
挙動やUIの変更処理などを実行
Gameplay Effect
Gameplay Ability Systemの構成要素
AbilitySystemComponent
○ GameAbilitySystemを使用するActorは
このコンポーネントを必ず持つ必要がある
RPGCharacterBase.cpp にて
ARPGCharacterBase::ARPGCharacterBase()
{
AbilitySystemComponent =
CreateDefaultSubobject<URPGAbilitySystemComponen
t> (TEXT("AbilitySystemComponent"));
…
Gameplay Ability Systemの構成要素
Gameplay Attribute (Sets)
○ Gameplay Ability Systemによって
制御・管理されるパラメータ(群)
○ 変化したパラメータを
Actorのプロパティに反映する処理はここで行う
○ C++限定。BPでは作成不可能
Attribute Sets専用の関数
● PreGameplayEffectExecute
○ GamePlay Effectの実行直前
○ 変更を拒否したり、変更内容を変更したり
● PreAttributeChange /PreAttributeBaseChange
○ Attributeの変更処理時に呼び出される
○ 変更後の値に対してClamp処理をかけたり
● PostGameplayEffectExecute
○ GamePlay Effectの実行直後
○ Actorへの変更う通知はここで
Gameplay Ability Systemの構成要素
ActionRPGでは、キャラクタのパラメータを管理
○ Health, Mana, Damage, MoveSpeed
RPGAttribute.hにて
UPROPERTY(BlueprintReadOnly, Category = “Health”,
ReplicatedUsing=OnRep_Health)
FGameplayAttributeData Health;
ATTRIBUTE_ACCESSORS(URPGAttributeSet, Health)
Gameplay Ability Systemの構成要素
Gameplay Effect
○ Gameplay Attributeを制御するための機能
○ ダメージ値を元にHPを減らしたり、
一時的にパラメータを変更(バフ、デバフ)したり
デフォルトで用意されているプロパティを使って
どのようなルールでAttributeを制御するかを設定
○ 独自にカスタマイズする必要はなし
Gameplay Ability Systemの構成要素
Gameplay Ability
○ 対象のスキルが使った際の制御を管理
■ どのアニメーションを再生するか
■ どのGamePlay Effectを使用するか
■ 使用する際のコスト、条件の計算
○ C++, BPで実装
Gameplay Ability
Activate (OnEnd) Ability イベント
○ Commit Ability, End Abilityノード
○ Ability Taskノード
Ability Taskノード
GamePlay Ability用のノード
○ 非同期処理、イベントドリブン
○ C++で自作可能( RPGAbilityTask_PlayMontageAndWaitForEvent )
Actor側ですること
ActorがAbility System Component経由で
GamePlay Abilityを呼び出す
Gameplay Tagによるフィルタ機能
実行対象のAbility、実行中のAbility、
Source(実行元のActor), Target(実行対象のActor) が持つ
Tag情報を使って実行するか否かを判定可能
タグの活用例
Tag: none Tag: Status.Dead
Tag: Status.Dead Tag: Ability.Melee