Koalaエンジンは、エンティティコンポーネントシステム(ECS)として完全に実装されたゲームエンジンです。
エンジンはENTTに基づいています。 EnTTを使用して他のソフトウェアとの統合は簡単です。このドキュメントでは、少なくともEnTTとその用語( entity 、 registry 、 handle ...)の基本的な知識を想定しています。

この例は、コア機能のいくつかを紹介しています。それは、反射とランタイムの拡張性に対するエンジンのサポートが提供しなければならないものについてのアイデアを提供するはずです。
エンジンはgitサブモジュールを使用するため、再帰的にクローニングする必要があります
git clone https://github.com/phisko/kengine --recursive
エンジンは、MSVCとMINGWを使用してWindowsでテストされています。
LinuxコンピレーションはGCCで動作します。執筆時点では、ClangはC ++ 20のconstexpr std::stringおよびstd::vectorをサポートしていません。
エンジンにはC ++ 20コンパイラが必要です。
エンジンは、2016 - 17年に情熱/学生プロジェクトとして始まりました。私の友人/同僚と私は、ゼロからECを実装することに挑戦しました。私たちは絶対的なタイプの安全性と明確さを望んでいましたが、すでにテンプレートのメタプログラムをおもちゃにしていましたが、これはそれについてもっと学ぶチャンスでした。
コアECSが機能すると、エンジンはゲーム開発の詳細を学ぶために遊び場になりました。 OpenGLレンダリング、リキャスト/迂回路でNavmeshesを使用する方法、弾丸で物理学をセットアップする方法を学びました... ECSと互換性のある有用なヘルパーとランタイムリフレクション施設の開発。
エンジンで5年以上働いた後、私はコアECS自体がもはやこのプロジェクトの焦点ではないことに気付きました。他のライブラリ、特にEnTT 、はるかに高度な機能を備えた非常によく似たAPIを提供します。そこで、私は時間をかけて内部ECを完全に取り除き、それをEnTTに置き換えました。すべての機能は同じままであり、これにより、他のEnTTプロジェクトと連携できる有用なヘルパーに取り組む時間が増えます。
エンジンの多くの部分(スクリプトシステムやIMGUIエンティティエディターなど)は、 putilsの反射APIを使用しています。したがって、次のサンプルのコンポーネントのほとんどは、反射性があると定義されています。
エンジンコードは、3つのカテゴリで編成されています。
systems特定のクラスのオブジェクトではないことに注意してください。システムは、実行コンポーネント(または作業を行うために必要な他のもの)を備えた単なるエンティティです。エンティティは、ゲーム状態の残りの部分とともにregistryに存在します。これにより、ユーザーがシステムを内省したり、他のエンティティと同じように動作を追加したりすることができます。
これらの3つのカテゴリは、さまざまなライブラリに分割されます。
一部のライブラリにはサブライブリーが含まれていることに注意してください。
Cmakeセクションは、これらのライブラリを使用する方法の詳細について説明します。
このエンジンには、ゲームのブートストラップに使用できる、または単に独自の実装の基礎となる例として、(かなり大きな)事前に構築されたコンポーネントが付属しています。
これらのコンポーネントは3つのカテゴリに適合します。
データコンポーネントは、エンティティに関するデータを保持しています。
データコンポーネントは、変換や名前などのコンポーネントを考えるときに最初に思い浮かぶものです。
データコンポーネントは、機能を保持する場合があります。
関数コンポーネントは、エンティティをクエリ、変更、または通知する関数を保持します。
関数コンポーネントは、エンティティへのコンポーネントとして接続できる機能者の単純な保有者です。このメカニックは以下に慣れています。
関数コンポーネントは、base_functionから継承するタイプであり、テンプレートパラメーターとして関数署名を与えます。
関数コンポーネントを呼び出すには、 operator()またはcall関数を使用できます。
entt::registry r;
const auto e = r.create();
r.emplace<main_loop::execute>(e,
[]( float delta_time) { std::cout << " Yay! " << std::endl; }
);
const auto & execute = r.get<main_loop::execute>(e); // Get the function
execute ( 0 .f); // Call it with its parameters
execute.call( 42 .f); // Alternativelyメタコンポーネントは、コンポーネントのコンポーネントです。
エンジンは「タイプエンティティ」を使用して、使用中のさまざまなコンポーネントに関する情報を保持します。各タイプエンティティは異なるコンポーネントタイプを表し、実行時にコンポーネントのプロパティを照会するために使用できます。
メタコンポーネントはこれらの「タイプエンティティ」に添付されており、その特定のタイプの一般的な関数の実装を保持します。機能を保持しているため、関数コンポーネントに非常に似ています。
例として、これを明確にします。Meta:: imgui :: editは、呼び出されると、特定のエンティティにimguiを使用して「親コンポーネント」のプロパティを描画するメタコンポーネントです。次のコードには、 eの名前コンポーネントを編集するウィンドウが表示されます。
// r is a registry with the "type entity" for `name` already setup
const auto e = r.create();
r.emplace<core::name>(e);
const auto type_entity = type_helper::get_type_entity<core::name>(r);
const auto & edit = r.get<meta::imgui::edit>(type_entity);
if (ImGui::Begin( " Edit name " ))
edit ({ r, e });
ImGui::End ();これを一般化する場合は、次のコードを使用してエンティティのすべてのコンポーネントを編集できます。
// r is a registry with the "type entities" for all used components already setup
// e is an entity with an unknown set of components
if (ImGui::Begin( " Edit entity " ))
for ( const auto & [type_entity, edit] : r.view<meta::imgui::edit>()) {
edit ({ r, e });
}
ImGui::End ();各ライブラリを有効にする方法については、CMakeを参照してください。
Generate_Type_Registration Pythonスクリプトが提供されます。これは、特定のタイプのセットをエンジンに登録する関数を含むC ++ファイルを生成するために使用できます。
これは絶対に必須ではありません。
エンジンは、Cmakeをビルドシステムとして使用します。ライブラリの作成を簡素化するために、カスタムフレームワークが導入されています。ルートのcmakelistは、サブディレクトリを反復し、いくつかの条件と一致する場合、ライブラリとして自動的に追加します。
すべての有効なライブラリに対してリンクするベースのkengineインターフェイスライブラリが作成されているため、クライアントはそれに対して単純にリンクできます。
次のCmakeオプションが公開されています。
KENGINE_TESTSテストを実装するライブラリのテスト実行可能ファイルをコンパイルします。
KENGINE_NDEBUGデバッグコードを無効にします。
KENGINE_TYPE_REGISTRATIONエンジンタイプのタイプ登録コードが生成されます。これは、メタコンポーネントの実装を提供するため、エンジンの反射機能の多くの中心です。
KENGINE_GENERATE_REFLECTIONエンジンタイプの反射ヘッダーを更新します。これらは事前に生成されているため、エンジンのソースコードを変更しない限り、これを有効にする必要はありません。
不要な依存関係の構築を避けるために、すべてのライブラリがデフォルトで無効になっています。各ライブラリは、cmakeオプションをONに設定することにより、個別に有効にすることができます。オプション名については、ライブラリの命名を参照してください。
または、すべてのライブラリをKENGINE_ALL_SYSTEMSオプションで有効にすることができます。
サブライブリーは、親ライブラリを有効にする必要があることに注意してください:kengine_imgui_entity_editorにはkengine_imguiが必要です。
ライブラリは、エンジンルートへの相対パスに応じて名前が付けられています。パス内のスラッシュは、単にアンダースコアに置き換えられます。
kengine_corekengine_imgui_toolこれらの名前は次のとおりです。
KENGINE_CORE for kengine_core )kengine_coreのKENGINE_CORE_EXPORT )C ++定義マクロのおかげで、コンピレーション中にライブラリの存在をテストすることができます。これらは、cmakeオプションと同じ名前を持っています。
# ifdef KENGINE_CORE
// The kengine_core library exists
# endif一部のライブラリは、依存関係管理のためにVCPKGを使用しています。
ライブラリはroot CMakeLists.txtによって自動的に検出されるため、新しいライブラリを作成するのはかなり簡単です。
ライブラリは、すべてのライブラリ(log_helperやprofiling_helperなど)が使用する必要があるヘルパーを提供するため、 kengine_coreに対して自動的にリンクします。
サブライブリーは、親に対して自動的にリンクします。たとえば、kengine_imgui_entity_editorは、kengine_imguiに対して自動的にリンクします。
ライブラリのhelpersとsystemsサブディレクトリからのソースファイルは自動的に追加されます。ない場合、ライブラリはcmakeインターフェイスライブラリになります。
タイプ登録および反射コードは、コンポーネントに対して自動的に生成される場合があります。デフォルトでは、ライブラリのdataとfunctionsサブディレクトリ内のすべてのヘッダーは、生成スクリプトに渡されます。
ソースファイルと同様に、 *.tests.cppファイルがライブラリのhelpers/testsまたはsystems/testsサブディレクトリにある場合、GoogleTestの実行可能ファイルが自動的に追加されます。
CMakeLists.txt基本的なライブラリは、ソースファイルが自動的に行われるため、独自のCMakeLists.txtを必要としません。ただし、ライブラリにカスタム動作が必要な場合(たとえば、追加のソースを追加するか、サードパーティライブラリにリンクするために)、独自のCMakeLists.txtを追加する場合があります。そのCMakeLists.txt 、 add_libraryへの呼び出しの後に呼び出されます。
CMakeLists.txtを呼び出す前に、次の変数と関数は定義されます。
kengine_library_name :ライブラリの名前kengine_library_tests_name :ライブラリのGoogleTestターゲットの名前link_type :ライブラリのリンクタイプ(ソースが見つかったかどうかに応じて、 PUBLICまたはINTERFACE )kengine_library_link_public_libraries(libraries) :他のライブラリに対するリンク(公開)kengine_library_link_private_libraries(libraries) :他のライブラリに対するリンク(個人的に)register_types_from_headers(headers) :タイプの登録と反射ヘッダーを生成できるヘッダーを追加しますsubdirectory_is_not_kengine_library(path) :root CMakeLists.txtに、Kengine Libraryとしてpathを処理してはならないことを示します