このページはEaaSの3.6.8を対象にしています。
更新履歴
このページでは新しいノードをC++で作る方法についてまとめます。 このページではC++のソースコードの書き方について扱い、 ソースファイルをプロジェクトに追加する方法については扱いません。 ソースファイルをプロジェクトに追加する方法についてはこのページを参照してください。
C++で新しいノードを作るには、 CFlowBaseNode<eNCT_Instanced>またはCFlowBaseNode<eNCT_Singleton>を継承したクラスを作り、 そのクラスをREGISTER_FLOW_NODEで登録します。 次に2つの入力をとり、その和を出力するノードのコードを示します。
#include "StdAfx.h" #include "FlowBaseNode.h" class CMyNodesMyNode: public CFlowBaseNode<eNCT_Instanced> { enum EInPorts { Calc, A, B, }; enum EOutPorts { Sum, }; public: CMyNodesMyNode(SActivationInfo * pActInfo) { } virtual IFlowNodePtr Clone(SActivationInfo *pActInfo) { return new CMyNodesMyNode(pActInfo); }; virtual void GetMemoryUsage(ICrySizer * s) const { s->Add(*this); } virtual void GetConfiguration(SFlowNodeConfig& config) { static const SInputPortConfig in_config[] = { InputPortConfig_Void("Calc", _HELP("Calc sum of A and B.")), InputPortConfig<int>("A", _HELP("Value A")), InputPortConfig<int>("B", _HELP("Value B")), { 0 } }; static const SOutputPortConfig out_config[] = { OutputPortConfig<int>("Sum", _HELP("Sum of A and B.")), { 0 } }; config.sDescription = _HELP("Calc sum of A and B."); config.pInputPorts = in_config; config.pOutputPorts = out_config; config.SetCategory(EFLN_APPROVED); } virtual void ProcessEvent(EFlowEvent event, SActivationInfo* pActInfo) { switch (event) { case eFE_Activate: if (!IsPortActive(pActInfo, Calc)) break; ActivateOutput(pActInfo, Sum, GetPortInt(pActInfo, A) + GetPortInt(pActInfo, B)); break; } } }; REGISTER_FLOW_NODE("MyNodes:MyNode", CMyNodesMyNode);
このコードをメモ帳などで「CRYENGINE_GameCode_PC_v3_6_8_2962\Code\CryEngine\CryAction\FlowSystem\Nodes\MyNode.cpp」として保存します。 (※以下はWAF導入以前の方法です) 次にVisual Studioでこのファイルを「ソリューション->Game->CryAction->FlowSystem->Nodes」へ追加しコンパイルします。 これでFGで「MyNodes:MyNode」が使えるようになります。
継承するクラスにはインスタンス化(eNCT_Instanced)またはシングルトン(eNCT_Singleton)の2種類があります。 作成したノードをFGで複数配置した際、 eNCT_Instancedではそれぞれインスタンス化されメンバ変数も別々になりますが、 eNCT_Singletonではインスタンス化されずメンバ変数も共有されます。 また、eNCT_Singletonを選択した場合、Cloneメンバ関数は必要なく削除します。
入力ポート(Input Ports)を追加するには、 まずEInPorts構造体に値を追加し、 次にGetConfigurationメンバ関数のin_config配列にInputPortConfigを追加します。 InputPortConfigのテンプレート部分には入力ポートのタイプに合わせて「SFlowSystemVoid、int、 float、EntityId、Vec3、string、bool」からいずれかを指定します。 また、InputPortConfig_VoidまたはInputPortConfig_AnyTypeを指定することもできます。 1つめの引数には、入力ポートの名前を指定します。ただし、接頭辞とそれに続く「_(アンダースコア)」は、 プロパティエディタ(Property Editor)を使う場合にのみ指定してください。 2つ目の引数には入力ポートの説明を指定します。
入力ポートでは、いくつかの候補から選択するよう指定することもできます。 2つの方法があり、1つ目の方法はin_config配列で次のように指定します。
InputPortConfig<int>("A", _HELP("Value A"), 0, _UICONFIG("enum_int:One=1,Two=2,Three=3")),
この方法ではユーザーはOne、Two、Threeのいずれかから選択できます。
2つ目の方法は1つ目の方法はin_config配列で次のように指定します。
InputPortConfig<int>("B", _HELP("Value B"), 0, _UICONFIG("enum_global:vehicleLightTypes")),
この方法ではユーザーは「Scripts/Entities/Vehicles/Lights/DefaultVehicleLights.xml」の「type」に指定されたもののいずれかから選択できます。 この候補は、C++のEditorGame.cppのInitActionEnumsメンバ関数で指定されています。
出力ポート(Output Ports)を追加するには、 まずEOutPorts列挙体に値を追加し、 次にGetConfigurationメンバ関数のout_config配列にOutputPortCofigを追加します。 OutputPortCofigのテンプレート部分には出力ポートのタイプに合わせて「SFlowSystemVoid、int、 float、EntityId、Vec3、string、bool」からいずれかを指定します。 また、OutputPortConfig_VoidまたはOutputPortConfig_AnyTypeを指定することもできます。 1つめの引数には、出力ポートの名前を指定します。 2つ目の引数には出力ポートの説明を指定します。
単に入力ポートに反応する代わりに、 アップデートループを持つノードを作成することもできます。 そのためには次のように書きます。
pActInfo->pGraph->SetRegularlyUpdated( pActInfo->myID, true);
これでProcessEventメンバ関数にeFE_Updateのeventが来るようになります。 停止するには2つ目の引数にfalseを指定します。