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

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

Embed Size (px)

Citation preview

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

#ue4fest

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

瀬田 宗治奥井 健芹沢 仁

株式会社バイキング

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

#ue4fest

株式会社バイキング

多人数の通信対戦アクションゲームをよく作っている会社です

© 2012 SQUARE ENIX CO., LTD. All Rights Reserved.

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

#ue4fest

瀬田 宗治プログラマーグレート

マジシャンズデッドではモーションセンサーを使ってモノを掴んで

投げたりするギミックを担当

芹沢 仁火事場のプログラマーサーバー周り、UI、ツール等幅広く開発を担当

奥井 健癒し系プログラマー「ガンスリンガーストラトス」「マジシャンズデッド」でカメラやアニメーションシステムを担当

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

#ue4fest

本日の話

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

•BPからC++への移行

•モジュール分割

•プロジェクトの運用

•アニメーション

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

#ue4fest

「マジシャンズ・デッド」プロジェクト概要

• 開発人数プランナー: 6人プログラマ:18人モーション: 8人デザイナ :35人サウンド : 2人

• 開発期間約18ヶ月

• UEのバージョン4.6~4.12

• 非同期通信3対3オンラインアクションゲーム

• 非接触入力デバイス

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

#ue4fest

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

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

#ue4fest

初めてのUE4

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

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

#ue4fest

S氏曰く

「まずはBPでロジックを組むといいよ」

「後でボトルネックになったとこをネイティブ化したらいいよ」

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

#ue4fest

この言葉で私たちは

「時代はBPだ!全部BPで書けば良いんだ!」

とBP信者になりました。

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

#ue4fest

BPだと同時に編集できない問題は

ActorComponentで分割すれば解決するはず!

とコンポーネント分割を推し進める

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

#ue4fest

BPでできたActorComponentを継承したBP、

さらにそれを継承したBP、どんどん複雑化していく部品たち

だんだんプロジェクトも大きくなってきた

アセットも増えてきた

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

#ue4fest

急に問題が出始める

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

#ue4fest

• BPインターフェースは検索に引っかからない!どういうことだ!!

• なんかコンパイルに待たされるようになってきた!

• フレームレートが出ない

• 処理の流れを確認したい、デバッグしよう、うん?なんか変数の値が見れないぞ?ファンクションライブラリに書くと見れない?

• やっぱりマージができない!

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

#ue4fest

• BPインターフェースは検索に引っかからない!どういうことだ!! (現在は解決済み)

• なんかコンパイルに待たされるようになってきた!

• フレームレートが出ない

• 処理の流れを確認したい、デバッグしよう、うん?なんか変数の値が見れないぞ?ファンクションライブラリに書くと見れない? (現在は解決済み)

• やっぱりマージができない!

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

#ue4fest

• なんかコンパイルに待たされるようになってきた!

• フレームレートが出ない

• 処理の流れを確認したい、デバッグしよう、うん?

• やっぱりマージができない!

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

#ue4fest

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

どうやらBPの被参照数が多いほどコンパイルに時間がかかる事がわかった

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

#ue4fest

被参照数は以下の要領でどんどん増えていく

• 変数でBPを保持された• SpawnActorでBPを生成された• BPが継承された

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

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

#ue4fest

被参照数は以下の要領でどんどん増えていく

• 変数でBPを保持された• SpawnActorでBPを生成された• BPが継承された→BPを1つ継承すると、継承元の全てのBPクラスの被参照数が増える

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

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

#ue4fest

BpClass1

BpClass2

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

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

#ue4fest

BpClass1

BpClass2

BpClass3

BpClass3

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

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

#ue4fest

BpClass1

BpClass2

BpClass3

派生先の末端まで非参照として追加されるBpClass3

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

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

#ue4fest

4 0.8sec8 1.6sec16 2.0sec32 3.8sec:

※Intel(R) Core(TM) i7-5820K 3.30GHz 6コアにて計測

実際にコンパイル時間を計測

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

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

#ue4fest

4 0.8sec8 1.6sec16 2.0sec32 3.8sec:

256 33sec

※Intel(R) Core(TM) i7-5820K 3.30GHz 6コアにて計測

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

実際にコンパイル時間を計測

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

#ue4fest

マジシャンズ・デッドでは350以上の参照を持つBPも!

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

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

#ue4fest

マジシャンズ・デッドでは350以上の参照を持つBPも!基底クラスをC++化する事で改善

C++の基底クラスを用意

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

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

#ue4fest

• なんかコンパイルに待たされるようになってきた!

• フレームレートが出ない

• 処理の流れを確認したい、デバッグしよう、うん?

• やっぱりマージができない!

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

#ue4fest

フレームレートが出ない

• BPの構造体は値渡し• 想定外の挙動

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

#ue4fest

フレームレートが出ない

GetArray、GetArray2がそれぞれ10個の配列を返す場合

10 10

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

#ue4fest

フレームレートが出ない

GetArrayは111回GetArray2は210回呼ばれる

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

#ue4fest

フレームレートが出ない

•Pure関数は参照時に実行される

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

#ue4fest

フレームレートが出ない

•Pure関数は参照時に実行される

•ForEachLoopマクロは要素数の取得の為、内部で要素数+1だけGetArrayを呼び出している

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

#ue4fest

フレームレートが出ない

•Pure関数は参照時に実行される

ForEachLoopマクロ内

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

#ue4fest

フレームレートが出ない

•Pure関数は参照時に実行される要素数比較

ForEachLoopマクロ内

要素毎の処理

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

#ue4fest

フレームレートが出ない

•Pure関数は参照時に実行される

•ForEachLoopマクロは要素数の取得の為、内部で要素数+1だけGetArrayを呼び出している

•ForEachLoopのArray Elementを参照する時も呼び出される

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

#ue4fest

フレームレートが出ない

110

100

11

100

Pure関数の呼び出し回数

10 10

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

#ue4fest

フレームレートが出ない

110

100

11

100

Pure関数の呼び出し回数

10 10

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

#ue4fest

フレームレートが出ない

Pure関数の呼び出し回数

UFUNCTION(BlueprintPure)

const TArray<FVector>& GetArrayNative() const { return m_array; }

UFUNCTION(BlueprintPure)

const TArray<FVector>& GetArrayNative2() const { return m_array2; }

GetArray、GetArray2をC++に置き換えた

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

#ue4fest

フレームレートが出ない

Pure関数の呼び出し回数•GetArray 0.134ms→0.057ms

•GetArray2 0.146ms→0.083ms

GetArray、GetArray2をC++に置き換えた

UFUNCTION(BlueprintPure)

const TArray<FVector>& GetArrayNative() const { return m_array; }

UFUNCTION(BlueprintPure)

const TArray<FVector>& GetArrayNative2() const { return m_array2; }

負荷が軽減!

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

#ue4fest

• なんかコンパイルに待たされるようになってきた!

• フレームレートが出ない

• 処理の流れを確認したい、デバッグしよう、うん?

• やっぱりマージができない!

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

#ue4fest

デバッグしよう、うん?

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

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

#ue4fest

デバッグしよう、うん?

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

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

#ue4fest

デバッグしよう、うん?

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

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

#ue4fest

デバッグしよう、うん?

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

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

#ue4fest

• なんかコンパイルに待たされるようになってきた!

• フレームレートが出ない

• 処理の流れを確認したい、デバッグしよう、うん?

• やっぱりマージができない!

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

#ue4fest

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

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

#ue4fest

BP部分のNative化が始まる

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

#ue4fest

Native化に苦しめられる

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

#ue4fest

Native化に苦しめられる

•失って気づくBPのやさしさ

•BpEnum、Bp構造体の問題

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

#ue4fest

•失って気づくBPのやさしさ・nullptrをアクセスする事によるハング

•BpEnum、Bp構造体の問題

Native化に苦しめられる

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

#ue4fest

•失って気づくBPのやさしさ・nullptrをアクセスする事によるハング

•BpEnum、Bp構造体の問題・ Native化しようとしているBpで使用されている全てのBpEnum、Bp構造体をC++に変更しないとNative化できない

Native化に苦しめられる

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

#ue4fest

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

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

#ue4fest

マジシャンズデッドでのBPガイドライン

•デザイナが触るBPとプログラマが触るBPをできるだけ分ける

•BPクラスを継承したBPクラスを作らない

•BPクラスは自作のC++クラスを継承させる

•Enum、構造体はC++で定義する

•メンバ変数はC++で用意する

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

#ue4fest

マジシャンズデッドでのBPガイドライン

•デザイナが触るBPとプログラマが触るBPをできるだけ分ける→競合対策

•BPクラスを継承したBPクラスを作らない

•BPクラスは自作のC++クラスを継承させる

•Enum、構造体はC++で定義する→Native化対策

•メンバ変数はC++で用意する→デバッグ対策

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

#ue4fest

まとめ

•BP、C++の使い分けを考える

•BPからC++への移行はコストがかかる

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

#ue4fest

まとめ

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

•BPからC++への移行はコストがかかる

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

#ue4fest

まとめ

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

•BPからC++への移行はコストがかかる・移行する可能性があるなら最初からC++で作る

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

#ue4fest

結論

Blueprintは 恋人

結婚するなら C++

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

#ue4fest

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

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

#ue4fest

BPからC++への移行

1. SpawnActorに引数を渡したい場合

2. GC起因の不正アクセス

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

#ue4fest

SpawnActorに引数を渡したい

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

#ue4fest

BPの場合

1. Actorを作成

2. BPに変数を作成

3. 変数を選択して

Editable と

Expose on Spawn に

チェックを入れる

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

#ue4fest

BPの場合4. SpawnActorFromClassノードでアクタを指定

5. 引数がノードにあらわれるので設定

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

#ue4fest

C++の場合

1. SpawnActor の代わりに SpawnActorDeferred を使用

2. 変数を書き換えたり、関数呼び出したりする

3. FinishSpawningActorを呼び出す

OnConstruction や BeginPlay が呼ばれる前に値を設定可能

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

#ue4fest

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);

MyActor->bAttack = true; //攻撃状態で出現MyActor->SetSpeed(Speed); //速度設定

MyActor->FinishSpawning(Transform); // OnConstruction,BeginPlayが呼ばれる

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

#ue4fest

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

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

#ue4fest

GC(ガベージコレクション)によるクラッシュ

•何もしていないのにクラッシュ

•クラッシュのタイミングが不定

•BPで組んでいたときは発生していなかった

•突然ポインタの先が壊れる

GCによるクラッシュの可能性があります。

立っていただけなのにクラッシュ??

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

#ue4fest

UE4のGC(ガベージコレクション)

•不要となった UObject を定期的に自動削除する機能

•不要かどうかの判定は参照ツリーに含まれるかどうか

•GCの対象から外すためには UPROPERTY をつける

UPROPERTY

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

#ue4fest

参照ツリー

root set

Actor UObject

UObject

UObject

Actor

UPROPERTY

UPROPERTY

参照されていないUObjectはGC対象となる

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

#ue4fest

変数に UPROPERTY() をつけて参照を持つ.hclass GAME_API UMyObject : public UObject{}

class GAME_API AMyActor : public AActor{

UPROPERTY()UMyObject* MyObject;

};

.cpp

{

MyObject = NewObject<UMyObject>();

}

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

#ue4fest

参照ツリーに追加されているか注意

• クラスや構造体をメンバに持つ場合にも注意

• メンバを含んだクラスや構造体にも UPROPERTY が必要

• root set から参照がたどれているかを意識する

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

#ue4fest

参照ツリーから外れているケース.hUSTRUCT()struct FMyData{

UPROPERTY()UObject* MyObject; // 参照を持っているつもり

};

UCLASS()class GAMEMODULE_API AMyActor : public AActor{

GENERATED_BODY()

FMyData MyData; // ここで参照が切れている};

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

#ue4fest

途中で切れた参照ツリー

root set MyActor UMyObjectUPROPERTY

参照されていないためGC対象となる

FMyData

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

#ue4fest

参照ツリーにつながっているケース.hUSTRUCT()struct FMyData{

UPROPERTY()UObject* MyObject; // 参照を持つ

};

UCLASS()class GAMEMODULE_API AMyActor : public AActor{

GENERATED_BODY()

UPROPERTY()FMyData MyData; // 参照を持つ

};

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

#ue4fest

参照ツリーに繋がっている

root set MyActor UMyObjectUPROPERTY

参照されているためGC対象とならない

FMyDataUPROPERTY

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

#ue4fest

TArrayに格納する場合も同様.hUSTRUCT()struct FMyData{

UPROPERTY()UObject* MyObject; // 参照を持つ

};

UCLASS()class GAMEMODULE_API AMyActor : public AActor{

GENERATED_BODY()

UPROPERTY() // 参照を持つTArray<FMyData*> MyData;

};

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

#ue4fest

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

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

#ue4fest

モジュール構成

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

#ue4fest

UE4のモジュール

•エンジンそのものがモジュールの集まりで構成されている

•ゲームも複数のモジュールに分割することができる

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

#ue4fest

モジュール分割した経緯

•ビルド時間の短縮が見込めるはず

•ソースの依存度を減らしてスッキリ

•ツールやデバッグの機能も分割、リリース時は除外

とにかくやってみたかった!

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

#ue4fest

ソースの依存度を減らしたい

オブジェクト

オブジェクト

オブジェクト

適当に組むとこうなりがち

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

#ue4fest

ソースの依存度を減らしたい

オブジェクト

オブジェクト オブジェクト

こうしたい!

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

#ue4fest

モジュール単位でのコントロールは可能

拡張モジュール1

基本モジュール

拡張モジュール2

許可されていない方向の参照はビルドエラーにできる!

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

#ue4fest

モジュールの参照ルール

•モジュール間の依存度を下げるため一方通行の参照を設定

《ルール》• 各モジュールにレベルを設定• 下のレベルから上のレベルへの参照は可• 同じレベル内での水平参照も不可

《注意》• 相互依存はコンパイル時間に関して問題がある• 変数の静的初期化で問題を生じる場合がある

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

#ue4fest

モジュールの参照イメージ

中位のモジュール

下位のモジュール 下位のモジュール

上位のモジュール

参照

参照

参照

参照

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

#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

参照

方向

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

#ue4fest

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

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

#ue4fest

分割しすぎた

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

#ue4fest

モジュール分割のデメリット

•モジュール間の依存関係が複雑になる

•どのモジュールに作成すべきか考えないといけない

•モジュール間の移動に手間がかかる

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

#ue4fest

モジュール間を移動すると

クラス や 構造体 を異なるモジュールに移動

BPの参照が切れてアセットが壊れる

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

#ue4fest

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

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

#ue4fest

ActiveClassRedirects に指定

モジュール間を移動した場合は移動先のモジュールと名前をDefaultEngine.iniのActiveClassRedirectsに記述する

Game/Config/DefaultEngine.ini

[/Script/Engine.Engine]+ActiveClassRedirects=(OldClassName=“MyClass",NewClassName="/Script/BattleModule.MyClass ")

クラス名を変更したときにも使えるので便利!

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

#ue4fest

モジュール構成の提案

プロジェクト規模にもよりますがゲーム部分は数モジュールの分割で十分かも

例)• System

• Common

• Battle / OutGame

• Primary(ゲームプロジェクト名)

※ ツール、デバッグなどのモジュールは除く

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

#ue4fest

Systemモジュール

• System• システム共有の実装(他タイトルでも使用可能)

• アセット参照不可

• 可能なものは出来るだけプラグイン化を検討する

描画、アニメーション、サウンド、I/Oストレージなどの基本機能

• Common

• Battle / OutGame

• プライマリ

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

#ue4fest

モジュール構成図System

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

#ue4fest

Commonモジュール

• System

• Common• ゲームごとの実装ではあるが、

ゲームを通して共通の処理

• アセット参照可

ゲーム共通のアニメーション

• Battle / OutGame

• プライマリ

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

#ue4fest

モジュール構成図System

Common

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

#ue4fest

Battle/OutGameモジュール

• System

• Common

• Battle / OutGame• バトルとアウトゲームでは必要な機能が異なることが

多いので、それぞれ固有の実装はモジュールを分けるようにしてシンプルにする。

• プライマリ

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

#ue4fest

モジュール構成図System

Common

Battle OutGame

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

#ue4fest

モジュール構成例

• System

• Common

• Battle / OutGame

• Primary• とりあえず必要なのでこのへんに

• 全てのモジュールにアクセス可能な存在

• なるべく使用しない

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

#ue4fest

モジュール構成図System

Battle OutGame

Common

Primary

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

#ue4fest

UE4プロジェクトの運用

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

#ue4fest

作業PCスペック

•OS Windows10 Pro 64-bit

•CPU Intel Core i7 5820K 3.3GHz

•メモリ 16 GB

•グラフィック NVIDIA GeForce GTX 960

•SSD 500 GB

•HDD 2 TB

公式推奨よりもかなりイイ

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

#ue4fest

オススメはSSD

いまならNVMeのSSDがなおよし

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

#ue4fest

SSDの使用を推奨

大幅に作業時間が短縮できました

•ビルド時間の短縮

•UE4起動時間の短縮

•アセット読み込み・保存時間の短縮

•いろいろはかどります

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

#ue4fest

プロジェクト管理

Subversionを使用

• UE4インテグレートがされている

• スタッフの習熟度がPerforceよりも高い

• Gitはbeta版なので見送り

• 無料

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

#ue4fest

非プログラマの場合

• エディタのソースコントロールを使用

• エディタからコミット

• アセットがコミット対象

メリット

• 手軽でわかりやすい

デメリット

• 参照時にsvnのステータスをサーバに問い合わせるので動作が重い(サーバの混雑度合いによる)

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

#ue4fest

プログラマの場合

• コミット対象• BPソースファイル

• Cソースファイル

• exe

• dll

• pdb(デバッグに必要)

など

• TortoiseSVNを使用

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

#ue4fest

プログラマの作業フロー

1. プロジェクト更新

2. Cソースを更新して実装

3. ビルドして実行確認

4. Cソース、モジュールのdll、pdbをコミット

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

#ue4fest

ちょっと問題が

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

#ue4fest

dllコミット時にコンフリクトが発生

•Cソースは基本的にはマージされますが、dllはバイナリのためマージ不可。

•同じモジュールのCソースを同時に編集した場合コンフリクトが起きる。

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

#ue4fest

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

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

#ue4fest

Jenkinsによる自動ビルド

•プログラマはソースファイルをコミット

• Jenkinsがコミットを検知してdllを作成

•作成したdllをコミット

dllのコンフリクトが解決された!

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

#ue4fest

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

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

#ue4fest

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

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

#ue4fest

excludeを指定

•プログラマはdllをローカルでビルドするためコンフリクトが発生

•ローカルのものだけを信用すればよいのでリポジトリのdllは不要

•exclude指定することでローカルのみSubversion管理から外す

svn update --set-depth exclude BppGame¥Binaries¥Win64¥UE4Editor-SystemModule.dll

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

#ue4fest

他にも問題が

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

#ue4fest

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

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

#ue4fest

pdbファイルが原因

•サイズが大きいためストレージとネットワークの帯域を消費してしまう。

•通常は不要だけどデバッグ時に必要なので管理はしたい

Subversion管理せず、シンボルサーバを利用

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

#ue4fest

Jenkinsに任せていたこと

•dllのビルドと更新

•dllビルドエラーチェック

•パッケージ作成

•筐体へのインストール&ゲーム起動

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

#ue4fest

ビルドエラーが発生した場合

• JenkinsからSlackでプログラマにエラーを通知して知らせる

エラー時とエラー復帰時に通知

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

#ue4fest

まとめ

•参照ツリーを意識する

•モジュールは分割しすぎない

(無理に分割する必要はない)

•SSDがおすすめ

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

#ue4fest

アニメーション

1.アニメーションの共有、

2.ステート管理、3.AnimGraphはどう作ればええの?

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

#ue4fest

1.アニメーションの共有

•モデルが変わると同じアニメーションが再生できない??

•AnimGraphが共有できない??

Skeletonを1個にする!

結論

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

#ue4fest

•1つのSkeletonに全キャラの骨がマージされる(722本あった)

•モデルに存在しない骨は無視されるので大丈夫!

•骨の名前がかぶらないように注意

ドラゴンも一緒

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

#ue4fest

とりあえずこれをやれば再生できる1

骨ごとにリターゲットの設定

キャラ固有骨、顔 Animation

アニメーションで骨の位置を動かす骨 AnimationScale

アニメーションで骨の位置を動かさない骨 Skeleton

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

#ue4fest

とりあえずこれをやれば再生できる2

•SkeletonのRetargetManagerで設定

•キャラ固有モーションを作る時に必要(後で説明)

•登録するモデルはメモリ削減のためマテリアル無しのモデルにする

リターゲットソース

キャラモデルへの参照がいっぱい

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

#ue4fest

足が浮く!埋まる!

「骨の構造に問題がある場合1」

Root

COG

(腰の移動値)

これ、ダメ

•腰の移動値を入れる骨とRootの間に骨を追加してはいけない

•ボーンスペースのTrans値を元に倍率が計算されるので途中に骨があると正しい倍率でリターゲットされない

•ただし、Rootと同じ位置に追加する分には大丈夫

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

#ue4fest

足が浮く!埋まる!

「骨の構造に問題がある場合2」

極端な例

•「ひざ上」と「ひざ下」の比率が違うと足を曲げた時に高さが変わる。左の例は直立している時は同じ長さだけど曲げるとズレる

•よくあるのが「ハイヒール」

•すこしくらいならIKでごまかす

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

#ue4fest

足が浮く!埋まる!

キャラ固有モーションとは?•リターゲットしなくてもいいモーション

•キャラ専用のリグで出力したモーションのこと

この設定を間違えると足が浮いたり埋まったりする

ここでどのキャラ固有なのかを指定しないといけない

リターゲットマネージャで登録した名前が出てくる

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

#ue4fest

足が浮く!埋まる!

この設定、アセットごとに手動で設定しないといけない・・・

そんなんいややー!

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

#ue4fest

自動化しました• アニメーションインポートプラグインを作成した

• コンテンツブラウザの右クリックにアイコンを追加

• 特定のキャラのモーションを一括でインポート

• 更新されているかはハッシュ値で比較

• インポートするフォルダ名からリターゲットソースの値を生成して設定

• Additive設定、Notify、MetaDataなどの設定はテンプレート(主人公)から自動でコピー

• モンタージュやブレンドスペースの自動生成、AnimBPのアセットの参照付け替えの自動化

プラグインの作り方:http://historia.co.jp/archives/367

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

#ue4fest

アセットのロード•ファイル名でStaticLoadする。キャラごとのアセット名は同じ

例:

•ゲーム起動時に各キャラごとにアニメーションアセットのパスを生成

•パスの生成ルールは以下の順にファイルの存在チェックをして優先度の高いものが使われる

キャラ固有モーション 性別共通 共通

Pl001/Animation/co0000_Idle

Pl200/Animation/co0000_Idle

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

#ue4fest

アニメーション使う時•標準のPlayAnimationは直接使わなかった

• 引数にアセット設定したらコードを再利用できない

• Idを指定して再生するPlayAnimationを作った

•こうしておくとキャラを新規追加してもすぐにゲームでプレイできる

•データがない場合は共通モーション(主人公のモーション)が再生される

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

#ue4fest

骨の階層を変更しようとすると面倒

対処法1. 古いモデルを削除

2. 共通スケルトンを開き、TransrationRetargettingの設定をメモ(3番の手順をするとずれてしまうので)

3. Asset→RemoveUnusedBonesFromSkeletonを実行し、古い骨を削除

4. 新しい骨のモデルをインポート

5. メモしておいたTransrationRetargettingの設定を見ながらずれている部分を修正

6. リターゲットマネージャでリターゲットソースを再設定

7. 全モーション再インポート

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

#ue4fest

共通だけど変えたい(´・ω・`)•ヤラレは共通モーション

•武器を持っていると手が不自然、小物がめり込んじゃう

•部分的に上書きしたい、データドリブンに・・・

•DyanmicLayerBlendというノード実装した

修正前 修正後

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

#ue4fest

使用したデータ

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

#ue4fest

2.ステート管理について

BeginAction アクション起動時によばれる

EndAction アクション終了時によばれる

ActionTick アクションが起動中のみ毎フレよばれる

LocalActionTick クライアントのみよばれる版

CheckShiftableAction 指定アクションへの遷移が可能かを定義

•Actionという単位でクラスを作ってそれを切り替えて管理

•ながらアクションが可能なようにMainとSubの2レイヤー使えるようにした

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

#ue4fest

2.ステート管理について

ゲームシステム側のステートマシンは良いとして

↑これ、AnimBPのステートマシンを使うべきか、使わざるべきか

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

#ue4fest

AnimBPステートマシンのメリット・デメリット

■メリット•通信量が抑えられる

•ゲームシステム側のステートや移動量などすでに同期済みのステートを参照してアニメーションを切り替える場合

■デメリット•キャラごとにカスタマイズできない

•ゲームシステムのステートマシンと二重管理になる

•通常行動でモンタージュが使いづらい

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

#ue4fest

•マジシャンズデッドでは使わなかった

•もっと大人数の通信対戦だったら使ったほうがいいかもしれない

マジシャンズデッドではどうしたか

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

#ue4fest

ネットワーク同期はアニメーション単位

•アクション遷移はRPCで送って同期する

•アクション個別の処理は基本クライアントのみLocalActionTickに書く

•アニメーションの再生タイミングをRPCで同期する

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

#ue4fest

エフェクトやSe、ヒット判定など同期は?

•可能な限りAnimNotifyに仕込む

•AnimNotifyとはアニメーションの特定フレームでイベントを発生させるための機能です

•→はとある格闘3段目のNotify

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

#ue4fest

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

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

#ue4fest

3.AnimGraph

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

#ue4fest

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

#ue4fest

AnimGraph親指

人差し指

中指

薬指

小指

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

#ue4fest

AnimGraph

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

#ue4fest

アニメーションが無い=歩き

•アニメーションはSlotに流す

•Slotが空だとSourceのブレンドスペース(歩き)が出る

•攻撃中はエイミングポーズを上半身にブレンド

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

#ue4fest

補助骨やキャラ固有処理はどこに書く?

•Post Process AnimBPに書くと良い

•UE4.14で実装された。もっと早く欲しかった・・・

•「SkeletalMeshに設定できる」第2のAnimBP

•ラグドールなど物理の後に実行されるので補助骨に最適

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

#ue4fest

まとめ

AnimBPはSkeletonと結合しているので再利用性が低くなりがち。でも大丈夫!

Skeletonを1個にすれば乗り切れる!

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

#ue4fest

おしまい

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

#ue4fest

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

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

#ue4fest