バイキング流UE4活用術 ~BPとお別れするまでの18ヶ月~

6.2K Views

October 12, 17

スライド概要

2017/10/8(日)に行われたUNREAL FEST EAST 2017における株式会社バイキング様の講演「バイキング流UE4活用術 ~BPとお別れするまでの18ヶ月~」で使用された資料です。

https://unrealevent.eventcloudmix.com/



スライドに埋め込まれた動画に関しましては、以下のURLにてご確認ください。

https://youtu.be/15CKcLAWSFU

profile-image

Unreal Engineを開発・提供しているエピック ゲームズ ジャパンによる公式アカウントです。 勉強会や配信などで行った講演資料を公開しています。 公式サイトはこちら https://www.unrealengine.com/ja/

シェア

埋め込む »CMSなどでJSが使えない場合

各ページのテキスト
1.

バイキング流UE4活用術 ~BPとお別れするまでの18ヶ月~ 株式会社バイキング 瀬田 宗治 奥井 健 芹沢 仁 #ue4fest

2.

株式会社バイキング 多人数の通信対戦アクションゲームをよく作っている会社です © 2012 SQUARE ENIX CO., LTD. All Rights Reserved. #ue4fest

3.

芹沢 仁 火事場のプログラマー サーバー周り、UI、ツール等幅広く開発を担当 瀬田 宗治 プログラマーグレート マジシャンズデッドではモーショ ンセンサーを使ってモノを掴んで 投げたりするギミックを担当 奥井 健 #ue4fest 癒し系プログラマー 「ガンスリンガーストラトス」「マジシャンズデッド」で カメラやアニメーションシステムを担当

4.

本日の話 • BP出会いから別れまでのストーリー • BPからC++への移行 • モジュール分割 • プロジェクトの運用 • アニメーション #ue4fest

5.

「マジシャンズ・デッド」 プロジェクト概要 • 開発人数 プランナー: 6人 プログラマ:18人 モーション: 8人 デザイナ :35人 サウンド : 2人 • 開発期間 約18ヶ月 • UEのバージョン 4.6~4.12 • 非同期通信3対3オンラインアクションゲーム • 非接触入力デバイス #ue4fest

6.

BP出会いから別れまでのストーリー #ue4fest

7.

初めてのUE4 どうしていいか分からなかったので ヒストリアさんにサポートをお願いしました #ue4fest

8.

S氏曰く 「まずはBPでロジックを組むといいよ」 「後でボトルネックになったとこをネイティブ化したらいいよ」 #ue4fest

9.

この言葉で私たちは 「時代はBPだ!全部BPで書けば良いんだ!」 とBP信者になりました。 #ue4fest

10.

BPだと同時に編集できない問題は ActorComponentで分割すれば解決するはず! とコンポーネント分割を推し進める #ue4fest

11.

BPでできたActorComponentを継承したBP、 さらにそれを継承したBP、どんどん複雑化していく 部品たち だんだんプロジェクトも大きくなってきた アセットも増えてきた #ue4fest

12.

急に問題が出始める #ue4fest

13.

• BPインターフェースは検索に引っかからない! どういうことだ!! • なんかコンパイルに待たされるようになってきた! • フレームレートが出ない • 処理の流れを確認したい、デバッグしよう、うん? なんか変数の値が見れないぞ?ファンクションライブラリに書 くと見れない? • やっぱりマージができない! #ue4fest

14.

• BPインターフェースは検索に引っかからない! どういうことだ!! (現在は解決済み) • なんかコンパイルに待たされるようになってきた! • フレームレートが出ない • 処理の流れを確認したい、デバッグしよう、うん? なんか変数の値が見れないぞ?ファンクションライブラリに書 くと見れない? (現在は解決済み) • やっぱりマージができない! #ue4fest

15.

• なんかコンパイルに待たされるようになってきた! • フレームレートが出ない • 処理の流れを確認したい、デバッグしよう、うん? • やっぱりマージができない! #ue4fest

16.

コンパイルに待たされるようになってきた! どうやらBPの被参照数が多いほど コンパイルに時間がかかる事がわかった #ue4fest

17.

コンパイルに待たされるようになってきた! 被参照数は以下の要領でどんどん増えていく • 変数でBPを保持された • SpawnActorでBPを生成された • BPが継承された #ue4fest

18.

コンパイルに待たされるようになってきた! 被参照数は以下の要領でどんどん増えていく • 変数でBPを保持された • SpawnActorでBPを生成された • BPが継承された →BPを1つ継承すると、継承元の全てのBPク ラスの被参照数が増える #ue4fest

19.

コンパイルに待たされるようになってきた! BpClass1 BpClass2 #ue4fest

20.

コンパイルに待たされるようになってきた! BpClass1 BpClass3 BpClass2 BpClass3 #ue4fest

21.

コンパイルに待たされるようになってきた! BpClass1 BpClass3 BpClass2 BpClass3 #ue4fest 派生先の末端まで 非参照として 追加される

22.

コンパイルに待たされるようになってきた! 実際にコンパイル時間を計測 4 8 16 32 : 0.8sec 1.6sec 2.0sec 3.8sec ※Intel(R) Core(TM) i7-5820K 3.30GHz 6コアにて計測 #ue4fest

23.

コンパイルに待たされるようになってきた! 実際にコンパイル時間を計測 4 8 16 32 : 256 0.8sec 1.6sec 2.0sec 3.8sec 33sec ※Intel(R) Core(TM) i7-5820K 3.30GHz 6コアにて計測 #ue4fest

24.

コンパイルに待たされるようになってきた! マジシャンズ・デッドでは350以上の参照を持つBPも! #ue4fest

25.

コンパイルに待たされるようになってきた! マジシャンズ・デッドでは350以上の参照を持つBPも! 基底クラスをC++化する事で改善 C++の基底クラスを用意 #ue4fest

26.

• なんかコンパイルに待たされるようになってきた! • フレームレートが出ない • 処理の流れを確認したい、デバッグしよう、うん? • やっぱりマージができない! #ue4fest

27.

フレームレートが出ない • BPの構造体は値渡し • 想定外の挙動 #ue4fest

28.

フレームレートが出ない 10 10 GetArray、GetArray2がそれぞれ10個の配列を返す場合 #ue4fest

29.

フレームレートが出ない GetArrayは111回GetArray2は210回呼ばれる #ue4fest

30.

フレームレートが出ない • Pure関数は参照時に実行される #ue4fest

31.

フレームレートが出ない • Pure関数は参照時に実行される • ForEachLoopマクロは要素数の 取得の為、内部で要素数+1だ けGetArrayを呼び出している #ue4fest

32.

フレームレートが出ない • Pure関数は参照時に実行される ForEachLoopマクロ内 #ue4fest

33.

フレームレートが出ない • Pure関数は参照時に実行される 要素毎の処理 要素数比較 ForEachLoopマクロ内 #ue4fest

34.

フレームレートが出ない • Pure関数は参照時に実行される • ForEachLoopマクロは要素数の 取得の為、内部で要素数+1だ けGetArrayを呼び出している • ForEachLoopのArray Element を参照する時も呼び出される #ue4fest

35.

フレームレートが出ない 10 10 11 110 100 100 Pure関数の呼び出し回数 #ue4fest

36.

フレームレートが出ない 10 10 11 110 100 100 Pure関数の呼び出し回数 #ue4fest

37.

フレームレートが出ない GetArray、GetArray2をC++に置き換えた UFUNCTION(BlueprintPure) const TArray<FVector>& GetArrayNative() const { return m_array; } UFUNCTION(BlueprintPure) const TArray<FVector>& GetArrayNative2() const { return m_array2; } Pure関数の呼び出し回数 #ue4fest

38.

フレームレートが出ない GetArray、GetArray2をC++に置き換えた UFUNCTION(BlueprintPure) const TArray<FVector>& GetArrayNative() const { return m_array; } UFUNCTION(BlueprintPure) const TArray<FVector>& GetArrayNative2() const { return m_array2; } 負荷が軽減! •GetArray 0.134ms→0.057ms Pure関数の呼び出し回数 •GetArray2 0.146ms→0.083ms #ue4fest

39.

• なんかコンパイルに待たされるようになってきた! • フレームレートが出ない • 処理の流れを確認したい、デバッグしよう、うん? • やっぱりマージができない! #ue4fest

40.

デバッグしよう、うん? • アタッチでメンバ変数が見づらい • アタッチでスタックトレース追うのが大変 • スタンドアローンでしか起きない不具合 #ue4fest

41.

デバッグしよう、うん? • アタッチでメンバ変数が見づらい • アタッチでスタックトレース追うのが大変 • スタンドアローンでしか起きない不具合 #ue4fest

42.

デバッグしよう、うん? • アタッチでメンバ変数が見づらい • アタッチでスタックトレース追うのが大変 • スタンドアローンでしか起きない不具合 #ue4fest

43.

デバッグしよう、うん? • アタッチでメンバ変数が見づらい • アタッチでスタックトレース追うのが大変 • スタンドアローンでしか起きない不具合 →結果、ログを残して再発を待つデバッグに #ue4fest

44.

• なんかコンパイルに待たされるようになってきた! • フレームレートが出ない • 処理の流れを確認したい、デバッグしよう、うん? • やっぱりマージができない! #ue4fest

45.

みんなBPがいやになってくる #ue4fest

46.

BP部分のNative化が始まる #ue4fest

47.

Native化に苦しめられる #ue4fest

48.

Native化に苦しめられる •失って気づくBPのやさしさ •BpEnum、Bp構造体の問題 #ue4fest

49.

Native化に苦しめられる •失って気づくBPのやさしさ ・nullptrをアクセスする事によるハング •BpEnum、Bp構造体の問題 #ue4fest

50.

Native化に苦しめられる •失って気づくBPのやさしさ ・nullptrをアクセスする事によるハング •BpEnum、Bp構造体の問題 ・ Native化しようとしているBpで使用されている全 てのBpEnum、Bp構造体を C++に変更しないとNative化できない #ue4fest

51.

結局、全部をNative化することは できなかった #ue4fest

52.

マジシャンズデッドでのBPガイドライン • デザイナが触るBPとプログラマが触るBPをできるだけ分ける • BPクラスを継承したBPクラスを作らない • BPクラスは自作のC++クラスを継承させる • Enum、構造体はC++で定義する • メンバ変数はC++で用意する #ue4fest

53.

マジシャンズデッドでのBPガイドライン • デザイナが触るBPとプログラマが触るBPをできるだけ分ける →競合対策 • BPクラスを継承したBPクラスを作らない • BPクラスは自作のC++クラスを継承させる • Enum、構造体はC++で定義する →Native化対策 • メンバ変数はC++で用意する →デバッグ対策 #ue4fest

54.

まとめ •BP、C++の使い分けを考える •BPからC++への移行はコストがかかる #ue4fest

55.

まとめ •BP、C++の使い分けを考える ・試作などは編集と反映のサイクルを短くできる ・デザイナのUIとして ・複数人で同時にBPを触るような規模のプロジェク トになるとつらい •BPからC++への移行はコストがかかる #ue4fest

56.

まとめ •BP、C++の使い分けを考える ・試作などは編集と反映のサイクルを短くできる ・デザイナのUIとして ・複数人で同時にBPを触るような規模のプロジェク トになるとつらい •BPからC++への移行はコストがかかる ・移行する可能性があるなら最初からC++で作る #ue4fest

57.

結論 Blueprintは 恋人 結婚するなら C++ #ue4fest

58.

BPからC++への移行 モジュール分割 UE4プロジェクトの運用 #ue4fest

59.

BPからC++への移行 1. SpawnActorに引数を渡したい場合 2. GC起因の不正アクセス #ue4fest

60.

SpawnActorに引数を渡したい #ue4fest

61.

BPの場合 1. Actorを作成 2. BPに変数を作成 3. 変数を選択して Editable と Expose on Spawn に チェックを入れる #ue4fest

62.

BPの場合 4. SpawnActorFromClassノードでアクタを指定 5. 引数がノードにあらわれるので設定 #ue4fest

63.

C++の場合 1. SpawnActor の代わりに SpawnActorDeferred を使用 2. 変数を書き換えたり、関数呼び出したりする 3. FinishSpawningActorを呼び出す OnConstruction や BeginPlay が呼ばれる前に値を設定可能 #ue4fest

64.
[beta]
C++の記述例
UWorld* World = GetWorld();
FTransform Transform(FVector(0.0f, 0.0f, 100.0f));
FVector Speed(10.0f, 0.0f, 0.0f);

auto* MyActor = World->SpawnActorDeferred<AMyActor>(AMyActor::StaticClass(), Transform);

#ue4fest

MyActor->bAttack = true;
MyActor->SetSpeed(Speed);

//攻撃状態で出現
//速度設定

MyActor->FinishSpawning(Transform);

// OnConstruction,BeginPlayが呼ばれる

65.

GC(ガベージコレクション)起因のクラッシュ #ue4fest

66.

GC(ガベージコレクション)によるクラッシュ • 何もしていないのにクラッシュ • クラッシュのタイミングが不定 • BPで組んでいたときは発生して いなかった • 突然ポインタの先が壊れる GCによるクラッシュの可能性が あります。 #ue4fest 立っていただけなのにクラッシュ??

67.

UE4のGC(ガベージコレクション) • 不要となった UObject を定期的に自動削除する機能 • 不要かどうかの判定は参照ツリーに含まれるかどうか • GCの対象から外すためには UPROPERTY をつける UPROPERTY #ue4fest

68.

参照ツリー Actor UPROPERTY UObject Actor UPROPERTY UObject root set 参照されていないUObjectはGC対象となる UObject #ue4fest

69.
[beta]
変数に UPROPERTY() をつけて参照を持つ
.h
class GAME_API UMyObject : public UObject
{
}
class GAME_API AMyActor : public AActor
{
UPROPERTY()
UMyObject* MyObject;
};
.cpp
{
MyObject = NewObject<UMyObject>();

}

#ue4fest

70.

参照ツリーに追加されているか注意 • クラスや構造体をメンバに持つ場合にも注意 • メンバを含んだクラスや構造体にも UPROPERTY が必要 • root set から参照がたどれているかを意識する #ue4fest

71.

参照ツリーから外れているケース .h USTRUCT() struct FMyData { UPROPERTY() UObject* MyObject; }; // 参照を持っているつもり UCLASS() class GAMEMODULE_API AMyActor : public AActor { GENERATED_BODY() FMyData MyData; }; #ue4fest // ここで参照が切れている

72.

途中で切れた参照ツリー 参照されていないためGC対象となる root set #ue4fest MyActor FMyData UPROPERTY UMyObject

73.

参照ツリーにつながっているケース .h USTRUCT() struct FMyData { UPROPERTY() UObject* MyObject; }; // 参照を持つ UCLASS() class GAMEMODULE_API AMyActor : public AActor { GENERATED_BODY() UPROPERTY() FMyData MyData; }; #ue4fest // 参照を持つ

74.

参照ツリーに繋がっている 参照されているためGC対象とならない root set #ue4fest MyActor UPROPERTY FMyData UPROPERTY UMyObject

75.
[beta]
TArrayに格納する場合も同様
.h
USTRUCT()
struct FMyData
{
UPROPERTY()
UObject* MyObject;
};

// 参照を持つ

UCLASS()
class GAMEMODULE_API AMyActor : public AActor
{
GENERATED_BODY()
UPROPERTY()
// 参照を持つ
TArray<FMyData*> MyData;
};

#ue4fest

76.

参照ツリーを意識しよう! #ue4fest

77.

モジュール構成 #ue4fest

78.

UE4のモジュール • エンジンそのものがモジュールの集まりで構成されている • ゲームも複数のモジュールに分割することができる #ue4fest

79.

モジュール分割した経緯 • ビルド時間の短縮が見込めるはず • ソースの依存度を減らしてスッキリ • ツールやデバッグの機能も分割、リリース時は除外 とにかくやってみたかった! #ue4fest

80.

ソースの依存度を減らしたい 適当に組むとこうなりがち オブジェクト オブジェクト オブジェクト #ue4fest

81.

ソースの依存度を減らしたい こうしたい! オブジェクト オブジェクト #ue4fest オブジェクト

82.

モジュール単位でのコントロールは可能 基本モジュール 拡張モジュール1 拡張モジュール2 許可されていない方向の参照はビルドエラーにできる! #ue4fest

83.

モジュールの参照ルール • モジュール間の依存度を下げるため一方通行の参照を設定 《ルール》 • 各モジュールにレベルを設定 • 下のレベルから上のレベルへの参照は可 • 同じレベル内での水平参照も不可 《注意》 • 相互依存はコンパイル時間に関して問題がある • 変数の静的初期化で問題を生じる場合がある #ue4fest

84.

モジュールの参照イメージ 上位のモジュール 参照 #ue4fest 参照 参照 下位のモジュール 参照 中位のモジュール 下位のモジュール

85.

マジシャンズデッドのモジュール構成 参照方向 #ue4fest レベル モジュール L0 EngineModule L1 SystemModule L2 NetworkModule, USBIOModule L3 CommonDataModule, UserDataModule, ResidentModule L4 ActorModule, ControllerModule, ServerModule L5 BppGame, BppGameEd L6 CharacterModule, HudModule L7 OutGameModule L8 BattleAIModule, BattleCharacterModule L9 DebugModule L10 DevelopEditorModule

86.

メリットは享受できたと思うのですが #ue4fest

87.

分割しすぎた #ue4fest

88.

モジュール分割のデメリット • モジュール間の依存関係が複雑になる • どのモジュールに作成すべきか考えないといけない • モジュール間の移動に手間がかかる #ue4fest

89.

モジュール間を移動すると クラス や 構造体 を異なる モジュールに移動 BPの参照が切れて アセットが壊れる #ue4fest

90.

モジュール間を移動するには #ue4fest

91.

ActiveClassRedirects に指定 モジュール間を移動した場合は移動先のモジュールと名前を DefaultEngine.iniのActiveClassRedirectsに記述する 例 Game/Config/DefaultEngine.ini [/Script/Engine.Engine] +ActiveClassRedirects=(OldClassName=“MyClass",NewClassName="/Script/BattleModule.MyClass ") クラス名を変更したときにも使えるので便利! #ue4fest

92.

モジュール構成の提案 プロジェクト規模にもよりますが ゲーム部分は数モジュールの分割で十分かも 例) • System • Common • Battle / OutGame • Primary(ゲームプロジェクト名) ※ ツール、デバッグなどのモジュールは除く #ue4fest

93.

Systemモジュール • System • システム共有の実装(他タイトルでも使用可能) • アセット参照不可 • 可能なものは出来るだけプラグイン化を検討する 例 描画、アニメーション、サウンド、I/O ストレージなどの基本機能 • Common • Battle / OutGame • プライマリ #ue4fest

94.

モジュール構成図 System #ue4fest

95.

Commonモジュール • System • Common • ゲームごとの実装ではあるが、 ゲームを通して共通の処理 • アセット参照可 例 ゲーム共通のアニメーション • Battle / OutGame • プライマリ #ue4fest

96.

モジュール構成図 System Common #ue4fest

97.

Battle/OutGameモジュール • System • Common • Battle / OutGame • バトルとアウトゲームでは必要な機能が異なることが 多いので、それぞれ固有の実装はモジュールを分ける ようにしてシンプルにする。 • プライマリ #ue4fest

98.

モジュール構成図 System Common Battle #ue4fest OutGame

99.

モジュール構成例 • System • Common • Battle / OutGame • Primary • とりあえず必要なのでこのへんに • 全てのモジュールにアクセス可能な存在 • なるべく使用しない #ue4fest

100.

モジュール構成図 System Common Battle OutGame Primary #ue4fest

101.

UE4プロジェクトの運用 #ue4fest

102.

作業PCスペック • OS • CPU • メモリ • グラフィック • SSD • HDD Windows10 Pro 64-bit Intel Core i7 5820K 3.3GHz 16 GB NVIDIA GeForce GTX 960 500 GB 2 TB 公式推奨よりもかなりイイ #ue4fest

103.

オススメはSSD いまならNVMeのSSDがなおよし #ue4fest

104.

SSDの使用を推奨 大幅に作業時間が短縮できました • ビルド時間の短縮 • UE4起動時間の短縮 • アセット読み込み・保存時間の短縮 • いろいろはかどります #ue4fest

105.

プロジェクト管理 Subversionを使用 • UE4インテグレートがされている • スタッフの習熟度がPerforceよりも高い • Gitはbeta版なので見送り • 無料 #ue4fest

106.

非プログラマの場合 • エディタのソースコントロールを使用 • エディタからコミット • アセットがコミット対象 メリット • 手軽でわかりやすい デメリット • 参照時にsvnのステータスをサーバに 問い合わせるので動作が重い (サーバの混雑度合いによる) #ue4fest

107.

プログラマの場合 • コミット対象 • BPソースファイル • Cソースファイル • exe • dll • pdb(デバッグに必要) など • TortoiseSVNを使用 #ue4fest

108.

プログラマの作業フロー 1. プロジェクト更新 2. Cソースを更新して実装 3. ビルドして実行確認 4. Cソース、モジュールのdll、pdbをコミット #ue4fest

109.

ちょっと問題が #ue4fest

110.

dllコミット時にコンフリクトが発生 • Cソースは基本的にはマージされますが、 dllはバイナリのためマージ不可。 • 同じモジュールのCソースを同時に編集した場合 コンフリクトが起きる。 #ue4fest

111.

dllはコミットせず自動で作成! #ue4fest

112.

Jenkinsによる自動ビルド • プログラマはソースファイルをコミット • Jenkinsがコミットを検知してdllを作成 • 作成したdllをコミット dllのコンフリクトが解決された! #ue4fest

113.

commit時のdllコンフリクトは解決されたが #ue4fest

114.

今度はupdate時にdllコンフリクトが発生 #ue4fest

115.

excludeを指定 • プログラマはdllをローカルでビルドするためコンフリクトが発生 • ローカルのものだけを信用すればよいのでリポジトリのdllは不要 • exclude指定することでローカルのみSubversion管理から外す 例 svn update --set-depth exclude BppGame¥Binaries¥Win64¥UE4Editor-SystemModule.dll #ue4fest

116.

他にも問題が #ue4fest

117.

プロジェクトの更新時間が長い? #ue4fest

118.

pdbファイルが原因 • サイズが大きいためストレージとネットワークの帯域を消費し てしまう。 • 通常は不要だけどデバッグ時に必要なので管理はしたい Subversion管理せず、シンボルサーバを利用 #ue4fest

119.

Jenkinsに任せていたこと • dllのビルドと更新 • dllビルドエラーチェック • パッケージ作成 • 筐体へのインストール&ゲーム起動 #ue4fest

120.

ビルドエラーが発生した場合 • JenkinsからSlackでプログラマにエラーを通知して知らせる エラー時とエラー復帰時に通知 #ue4fest

121.

まとめ •参照ツリーを意識する •モジュールは分割しすぎない (無理に分割する必要はない) •SSDがおすすめ #ue4fest

122.

アニメーション 1.アニメーションの共有、 2.ステート管理、 3.AnimGraphはどう作ればええの? #ue4fest

123.

1.アニメーションの共有 • モデルが変わると同じアニメーションが再生できな い?? • AnimGraphが共有できない?? 結論 Skeletonを1個にする! #ue4fest

124.

ドラゴンも一緒 • 1つのSkeletonに全キャ ラの骨がマージされる (722本あった) • モデルに存在しない骨は 無視されるので大丈夫! • 骨の名前がかぶらないよ うに注意 #ue4fest

125.

とりあえずこれをやれば再生できる1 骨ごとにリターゲットの設定 #ue4fest キャラ固有骨、顔 Animation アニメーションで骨の位置を動かす骨 AnimationScale アニメーションで骨の位置を動かさない骨 Skeleton

126.

とりあえずこれをやれば再生できる2 リターゲットソース • SkeletonのRetargetManagerで設定 • キャラ固有モーションを作る時に必要(後で説明) • 登録するモデルはメモリ削減のためマテリアル無し のモデルにする #ue4fest キ ャ ラ モ デ ル へ の 参 照 が い っ ぱ い

127.

足が浮く!埋まる! 「骨の構造に問題がある場合1」 • 腰の移動値を入れる骨とRootの間に 骨を追加してはいけない • ボーンスペースのTrans値を元に倍率 COG が計算されるので途中に骨があると (腰の移動値) 正しい倍率でリターゲットされない これ、ダメ Root #ue4fest • ただし、Rootと同じ位置に追加する 分には大丈夫

128.

足が浮く!埋まる! 「骨の構造に問題がある場合2」 極端な例 • 「ひざ上」と「ひざ下」の比率が 違うと足を曲げた時に高さが変わ る。左の例は直立している時は同 じ長さだけど曲げるとズレる • よくあるのが「ハイヒール」 • すこしくらいならIKでごまかす #ue4fest

129.

足が浮く!埋まる! キャラ固有モーションとは? • リターゲットしなくてもいいモーション • キャラ専用のリグで出力したモーションのこと この設定を間違えると足が浮いたり埋まったりする ここでどのキャラ固有なのかを指定 しないといけない リターゲットマネージャで登録した 名前が出てくる #ue4fest

130.

足が浮く!埋まる! この設定、アセットごとに手動で設定しないといけない・・・ そんなんいややー! #ue4fest

131.

自動化しました • アニメーションインポートプラグインを作成した • コンテンツブラウザの右クリックにアイコンを追加 • 特定のキャラのモーションを一括でインポート • 更新されているかはハッシュ値で比較 • インポートするフォルダ名からリターゲットソース の値を生成して設定 • Additive設定、Notify、MetaDataなどの設定は テンプレート(主人公)から自動でコピー • モンタージュやブレンドスペースの自動生成、 AnimBPのアセットの参照付け替えの自動化 プラグインの作り方:http://historia.co.jp/archives/367 #ue4fest

132.

アセットのロード • ファイル名でStaticLoadする。キャラごとのアセット名は同じ 例: Pl001/Animation/co0000_Idle Pl200/Animation/co0000_Idle • ゲーム起動時に各キャラごとにアニメーションアセットのパス を生成 • パスの生成ルールは以下の順にファイルの存在チェックをして 優先度の高いものが使われる #ue4fest キャラ固有モーション 性別共通 共通

133.

アニメーション使う時 • 標準のPlayAnimationは直接使わなかった • 引数にアセット設定したらコードを再利用できない • Idを指定して再生するPlayAnimationを作った • こうしておくとキャラを新規追加し てもすぐにゲームでプレイできる • データがない場合は共通モーション (主人公のモーション)が再生され る #ue4fest

134.

骨の階層を変更しようとすると面倒 対処法 1. 古いモデルを削除 2. 共通スケルトンを開き、TransrationRetargettingの設定をメモ(3 番の手順をするとずれてしまうので) 3. Asset→RemoveUnusedBonesFromSkeletonを実行し、古い骨を 削除 4. 新しい骨のモデルをインポート 5. メモしておいたTransrationRetargettingの設定を見ながらずれてい る部分を修正 6. リターゲットマネージャでリターゲットソースを再設定 7. 全モーション再インポート #ue4fest

135.

共通だけど変えたい(´・ω・`) • ヤラレは共通モーション • 武器を持っていると手が不 自然、小物がめり込んじゃ う • 部分的に上書きしたい、 データドリブンに・・・ • DyanmicLayerBlendという ノード実装した 修正前 #ue4fest 修正後

136.

使用したデータ #ue4fest

137.

2.ステート管理について • Actionという単位でクラスを作ってそれを切り替えて管理 • ながらアクションが可能なようにMainとSubの2レイヤー 使えるようにした BeginAction アクション起動時によばれる EndAction アクション終了時によばれる ActionTick アクションが起動中のみ毎フレよばれる LocalActionTick クライアントのみよばれる版 CheckShiftableAction 指定アクションへの遷移が可能かを定義 #ue4fest

138.

2.ステート管理について ゲームシステム側のステート マシンは良いとして ↑これ、AnimBPのステートマシンを使うべきか、 使わざるべきか #ue4fest

139.

AnimBPステートマシンのメリット・デメリット ■メリット •通信量が抑えられる • ゲームシステム側のステートや移動量などすでに同期済みのステート を参照してアニメーションを切り替える場合 ■デメリット •キャラごとにカスタマイズできない •ゲームシステムのステートマシンと二重管理になる •通常行動でモンタージュが使いづらい #ue4fest

140.

マジシャンズデッドではどうしたか •マジシャンズデッドでは使わ なかった •もっと大人数の通信対戦だっ たら使ったほうがいいかもし れない #ue4fest

141.

ネットワーク同期はアニメーション単位 • アクション遷移はRPCで送って同期する • アクション個別の処理は基本クライアント のみLocalActionTickに書く • アニメーションの再生タイミングをRPCで 同期する #ue4fest

142.

エフェクトやSe、ヒット判定など同期は? • 可能な限りAnimNotifyに仕込む • AnimNotifyとはアニメーション の特定フレームでイベントを発 生させるための機能です • →はとある格闘3段目のNotify #ue4fest

143.

アニメーションの再生タイミング さえ同期しとけばなんとかなる! #ue4fest

144.

3.AnimGraph #ue4fest

145.

#ue4fest

146.

AnimGraph 親指 人差し指 中指 薬指 小指 #ue4fest

147.

AnimGraph #ue4fest

148.

アニメーションが無い=歩き • アニメーションはSlotに流す • Slotが空だとSourceのブレンドスペース(歩き)が出る • 攻撃中はエイミングポーズを上半身にブレンド #ue4fest

149.

補助骨やキャラ固有処理はどこに書く? • Post Process AnimBPに書くと良い • UE4.14で実装された。もっと早く欲しかった・・・ • 「SkeletalMeshに設定できる」第2のAnimBP • ラグドールなど物理の後に実行されるので 補助骨に最適 #ue4fest

150.

AnimBPは まとめ Skeletonと結合しているので再利用性 が低くなりがち。でも大丈夫! Skeletonを1個にすれば乗り切れる! #ue4fest

151.

おしまい #ue4fest

152.

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

153.

#ue4fest