ゲームエンジンの中の話

6.6K Views

January 15, 22

スライド概要

シェア

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

関連スライド

各ページのテキスト
1.

ゲームエンジンの中の話 釜井政義 <@i_love_falcom> 2015/12/1 モバイル・コンシューマ「開発比較」勉強会 #3

2.

誰? ⚫ ⚫ ⚫ ⚫ ⚫ 釜井政義(@i_love_falcom) コンシューマでアクション系開発ばかり10数年 描画やシステム低層側実装が主な仕事 昔は(社内)インフラなんかもやってました バイク命

3.

注意! ゲームエンジンが提供する機能は、 • Game Editor(+Tool群) • Run-time Framework 大きく分けてこの二つに別れますが、 今日はRun-time Frameworkの話をします

4.

本日のお題 ⚫ ⚫ ⚫ ⚫ ゲームエンジンを理解する ゲームループ内で実行する処理 ゲームループ外の処理 まとめ

5.

ゲームエンジンを理解する

6.

ゲームエンジンを理解しようとするとき、 どこから手を付ければいい?

7.

取りあえずソースコードとか読んでみる?

9.

うん、無理!

10.

関連技術を確認しながらならどう?

12.

やっぱ、無理!

13.

じゃあどこから理解する?

14.

複雑でよく分からないなら、 基本に立ち戻ってシンプルに考える

15.

ゲームループ 開始 Yes 終了? No 更新 描画 終了 フレーム同期

16.

なぜゲームループ? ⚫ ⚫ ⚫ どんなRun-time Frameworkにも必ずある(はず) 最外の処理なので全体の流れを見るのに都合がいい 対象となるプラットフォームによって、目的のコードが何処 にあるのかある程度見当がつく ⚫ 例えばAndroidの場合、SurfaceViewを継承しているクラ スを探す等

17.

古典的ループ CPU 更新 描画 GPU待ち 同期 GPU CPU待ち 描画

18.

CPU-GPU並列ループ CPU GPU N Frame 描画 N Frame 描画 N+1 Frame 更新 同 期 N+1 Frame 描画 N+1 Frame 描画

19.

2スレッドループ CPU1 N Frame 更新 N+1 Frame 更新 同 期 CPU2 N-1 Frame 描画 N Frame 描画初期化 N Frame 描画 同 期 GPU N-1 Frame 描画 N Frame 描画

20.

2スレッド+ジョブ並列化ループ CPU1 CPU2 GPU CPU3~ N Frame 更新 N-1 Frame 描画 同 期 N-1 Frame 描画 CPU1/2発行ジョブ N+1 Frame 更新 N Frame 描画初期化 同 期 N Frame 描画 N Frame 描画

21.

2スレッド+ジョブ +非同期コンピュート並列ループ CPU1 CPU2 N Frame 更新 N-1 Frame 描画 同 期 N-1 Frame 描画 GPU GPGPU CPU3~ CPU1/2発行ジョブ N+1 Frame 更新 N Frame 描画初期化 同 期 N Frame 描画 N Frame 描画

22.

並列・非同期化の方向へ進化する事によって、 CPU/GPU使用率が向上! ⚫ ⚫ ⚫ 複雑なエンティティを大量に処理できるようになる 反面、入力~描画間レイテンシが増大 ⚫ 対戦格闘やシューティングなど、低レイテンシであることが 必須のゲームに向かない 描画で使用していない間、汎用計算リソースとしてGPUを使用 する事で、これまで出来なかった事が可能になった

23.

ゲームループ内で実行する処理

24.

ゲームループ内で実行する処理 ⚫ ⚫ ⚫ エンティティシステム(タスクシステム) ⚫ エンティティの生成と破棄、およびリソース管理 ⚫ エンティティ更新、休止管理 描画システム ⚫ 描画リソースの生成、破棄、解決処理 ⚫ 描画コマンドの発行、Kick ゲームステート ⚫ ゲームの状態・遷移管理 ⚫ ゲームシーン(ステージ)管理

25.

エンティティ ⚫ ⚫ ⚫ ⚫ ゲーム内オブジェクト全ての基底 エンティティシステムによって生成・破棄の管理を行う 通常一意のIDを持ち、これによって他のエンティティから検 索、参照する機能を提供する エンティティ間を疎結合にするため、メッセージ通信機能を 提供する場合も多い

26.

古典的なエンティティの例 class ClassicalEntity { public: void Register(); void Unregister(); 新しいエンティティを実装するには、 このクラスを継承して以下のように使う 1 2 3 4 const char * GetID(); ClassicalEntity & Find(const char * id); protected: virtual void Update(const float delta) = 0; virtual void Draw() {} 一意のIDを設定 更新処理をUpdateに実装 必要なら描画処理をDrawに実装 ClassicalEntity(const char * id) {} Register/Unregisterを使って自身の登録処理、 virtual ~ClassicalEntity() {} 登録解除処理を行う private: 5 Findを使って他エンティティを検索 std::string myId; };

27.

古典的なエンティティの問題点 ⚫ ⚫ 機能追加を行うため、多重継承、菱形継承問題が発生してし まう可能性が高い 不要な機能も継承して使うため、本来必要のない処理が行わ れてしまう可能性がある

28.

多重継承、菱形継承の例 Game Object Game Object Movable Object Collidable Object 乗りもの Animation Object 武器 Skeletal Object 戦車 Human Dog Cat

29.

is-a関係からhas-a関係へ Game Object Component 1 * Mesh Renderer Transform Rigid Body Animation Controller

30.

エンティティの更新処理 ⚫ ⚫ 更新処理は複数のステージに分ける事が一般的 ⚫ 更新タイミングによっての分類 ⚫ アニメーション処理前の更新 ⚫ 剛体物理処理後の更新 処理方法による分類 ⚫ ジョブを使った並列更新 ⚫ 他エンティティはRead参照のみ可 ⚫ 単一スレッドによる逐次更新 ⚫ 他エンティティをRead/Write参照可

31.

描画システム ⚫ ⚫ ⚫ ⚫ 全エンティティから描画情報(メッシュなど)を収集 ⚫ 更新・描画の並列化を行う場合ダブルバッファ化 収集した描画情報が描画対象となるかを判定 各描画パス毎に描画コマンドを生成、GPUへKick ⚫ ジョブが使用可能なら並列に描画コマンドを生成 使用しなくなった描画リソースの生存管理 ⚫ リソースを保持するエンティティが破棄されても、GPU 側で使用中の可能性があるのでリソースは描画システムが 管理する

32.

ゲームステート スタート タイトル ⚫ ⚫ ⚫ ⚫ ゲーム全体を管理するステート ステージ管理ステートなどを持つ場合、 ゲームステート下に階層的に持つ 各種イベントをここからトリガ ステートの内容をスクリプトで記述でき るようにしたエンジンも多い ステージ1 ステージ2 ステージ3 エンディング オプション

33.

ゲームループ外の処理

34.

ゲームループ外の処理とは、 描画と同期しなくない処理 ⚫ ⚫ ⚫ ⚫ ファイルのロード処理 各種リソースの初期化処理 ⚫ GPUリソースなどはゲームループと同期する必要がある サウンド処理 ネットワーク処理

35.

ファイルのロード処理 ⚫ ⚫ ⚫ ファイルをロードしている間、ゲームループを止めるわけに はいかない為、非同期ロードが必須 ファイルは通常圧縮されているので、解凍処理も行う 解凍されたリソースはリソースマネージャへ登録、解決処理 などを行う ⚫ 解決処理とは、名前などを用いて外部のリソースとの関 連付けを行う処理

36.

サウンド処理 ⚫ ゲームループが処理落ちしてしまった場合など、サウンドの 更新が同期しているとプチノイズ等が発生してしまう ネットワーク処理 ⚫ 通信データの送受信は、その時々のトラフィック状態によっ てレイテンシが大きく異なってしまうため、描画と同期する わけにはいかない

37.

まとめ ⚫ ⚫ ⚫ ゲームエンジンの処理は複雑でよく分からないが、ゲームル ープを追う事で全体的な流れを理解しやすくなる ゲームループはCPU、GPUの利用効率を上げることで大量の エンティティを扱うことができるようになったが、レイテン シが犠牲になるという面もある ゲームループの内で処理を行うか、外で行うかは、主に描画 と同期する必要があるかどうかで決まる

38.

更にゲームエンジンについて学ぶなら・・・

39.

絶賛発売中

40.

質問?