このページは、5.1.0を対象としています。
※5.1.0でUI Actions内でFlow Graph Moduleを使うと、保存・読込でそのノードが消えるバグがあるようです。
※Flow Graph Moduleを多用すると、レベルの読み込みが極端に遅くなります。 Flow Graph Moduleの使用は必要最低限にとどめるべきです。
更新履歴
Flow Graph Module System(以下単にモジュール)とは、他のFGから呼び出し可能なFG、つまりプログラミング言語でいう関数のような機能です。 Moduleの種類には、GlobalとLevelとの2種類があります。 Globalは全てのレベルから参照可能で、FGは「Assets/libs/FlowgraphModules」へ保存されます。 Levelは特定のレベルからのみ参照可能で、FGは「Assets/levels/<レベル名>/FlowgraphModules」へ保存されます。
モジュールを作成するには、次のようにFlow Graph Editorで、「File -> New FG Module... -> Global/Level」を選択します。
または、次のようにFlow Graphsウィンドウで「FG Modules」を右クリックし、「New Global FG Module/New Level FG Module」を選択します。
その後、名前を付けて保存ダイアログでファイル名を指定し保存をクリックします。 すると、次のようなデフォルトの2つのノードを含むFGが作成されます。
これらのデフォルトの2つのノードにリンクしてモジュールを作ります。 デフォルトの2つのノードは削除したりはできません。 デフォルトの2つのノードの詳細は以下の通りです。
Startノードの出力ポート
Endノードの入力ポート
モジュールを削除するには、次のようにFlow Graphsウィンドウで項目を右クリックし、「Delete Module」を選択します。 モジュールの削除はUndoできないので注意。
モジュールを呼び出すには、Module:Call_<モジュール名>ノードを使います。 このノードの詳細は以下の通りです。
入力ポート
出力ポート
モジュールのポートをカスタマイズするには、モジュールを開いてから、次のようにメニューから「Tools -> Edit Module」を選択します。
すると、入力ポートと出力ポートを追加できる次のようなダイアログが表示されます。
New Input/New Outputボタンを押すと、次のようなダイアログが表示されます。 Nameにはポートの名前を、Typeにはポートの型を指定します。 ポートの型に指定できるのは、Bool、EntityId、Int、Float、String、Vec3です。
OKをクリックすると、次のようにモジュールのノードとモジュール呼び出しのノードが新しい入力・出力ポートで更新されます。
例えば、二つのFloatを受け取り、その和を返すモジュールは次のように作ります。
モジュールに外部からアクセスするには、 IFlowgraphModuleManagerインターフェイスを使います。 また、C++からモジュールを呼び出すには、 GetModule関数でモジュールを取得した後、 CreateModuleInstance関数を使います。
次に前述したTestモジュールを呼び出す自作ノードの例を挙げます。
//written by ToyaShiwasu #include "StdAfx.h" #include <CryFlowGraph/IFlowBaseNode.h> #include "CryFlowGraph/IFlowGraphModuleManager.h" class CFlowNode_CallTestModuleNode : public CFlowBaseNode<eNCT_Instanced> { enum EInPorts { InAdd, InA, InB, }; enum EOutPorts { OutSum, }; float sum=0; bool isReturn=false; public: CFlowNode_CallTestModuleNode(SActivationInfo * pActInfo) {}; virtual void GetConfiguration(SFlowNodeConfig &config) { static const SInputPortConfig in_config[] = { InputPortConfig_AnyType("Add",_HELP("")), InputPortConfig<float>("a",_HELP("")), InputPortConfig<float>("b",_HELP("")), { 0 } }; static const SOutputPortConfig out_config[] = { OutputPortConfig<float>("sum",_HELP("")), { 0 } }; config.sDescription = _HELP(""); config.pInputPorts = in_config; config.pOutputPorts = out_config; config.SetCategory(EFLN_APPROVED); } void TestCallback(bool bSuccess, const TModuleParams& outputParams) { //module callback outputParams[0].GetValueWithConversion(sum); isReturn = true; } virtual void ProcessEvent(EFlowEvent evt, SActivationInfo *pActInfo) { switch (evt) { case eFE_Activate: if (IsPortActive(pActInfo, InAdd)) { IFlowGraphModuleManager* pModuleManager = gEnv->pFlowSystem->GetIModuleManager(); if (const IFlowGraphModule* pModule = pModuleManager->GetModule("Test")) { //call module TModuleParams inputParams; inputParams.resize(2); inputParams[0].Set(GetPortFloat(pActInfo, InA)); inputParams[1].Set(GetPortFloat(pActInfo, InB)); pModuleManager->CreateModuleInstance(pModule->GetId(), inputParams, functor(*this, &CFlowNode_CallTestModuleNode::TestCallback)); pActInfo->pGraph->SetRegularlyUpdated(pActInfo->myID, true); } } break; case eFE_Update: if (isReturn) { ActivateOutput(pActInfo, OutSum, sum); isReturn = false; pActInfo->pGraph->SetRegularlyUpdated(pActInfo->myID, false); } } }; virtual void GetMemoryUsage(ICrySizer * s) const { s->Add(*this); } }; REGISTER_FLOW_NODE("Module:CallTestModule", CFlowNode_CallTestModuleNode);
次のコンソール変数を使うことで、モジュールのデバッグ情報が表示される。