Re: node AI:Anim

#11
I found codes for AI: Anim.
Will I add these codes, does it work?

Code: Select all

CFlowNode_AIAnim::~CFlowNode_AIAnim() { OnCancel(); } void CFlowNode_AIAnim::OnCancelPortActivated( IPipeUser* pPipeUser, SActivationInfo* pActInfo ) { if ( m_iMethod == 2 ) // is method == Action? { pPipeUser->RemoveSubPipe( m_GoalPipeId, true ); OnCancel(); // only to reuse unregistering code } else pPipeUser->CancelSubPipe( m_GoalPipeId ); } void CFlowNode_AIAnim::OnCancel() { if ( m_pAGState ) { m_pAGState->RemoveListener( this ); switch ( m_iMethod ) { case 0: if ( !m_bStarted ) m_pAGState->ClearForcedStates(); break; case 1: if ( !m_bStarted ) m_pAGState->SetInput( "Signal", "none" ); m_pAGState->Hurry(); break; case 2: m_pAGState->SetInput( "Action", "idle" ); break; } m_pAGState = NULL; m_queryID = 0; m_bStarted = false; } } void CFlowNode_AIAnim::DestroyedState(IAnimationGraphState*) { m_pAGState = NULL; m_queryID = 0; m_bStarted = false; } void CFlowNode_AIAnim::OnEntityEvent( IEntity* pEntity, SEntityEvent& event ) { TBase::OnEntityEvent( pEntity, event ); if ( event.event == ENTITY_EVENT_POST_SERIALIZE ) { if ( IActor* pActor = gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(m_EntityId) ) { m_pAGState = pActor->GetAnimationGraphState(); if ( m_pAGState != NULL ) { m_pAGState->AddListener( "aianim", this ); if ( !m_bStarted ) { IAnimationGraphState::InputID inputID = (IAnimationGraphState::InputID) -1; switch ( m_iMethod ) { case 1: // use "signal" inputID = m_pAGState->GetInputId( "Signal" ); break; case 2: // use "action" inputID = m_pAGState->GetInputId( "Action" ); break; } if ( inputID != (IAnimationGraphState::InputID) -1 ) { char inputValue[256]; m_pAGState->GetInput( inputID, inputValue ); m_pAGState->SetInput( inputID, inputValue, &m_queryID ); } } else { if ( m_iMethod <= 1 ) m_pAGState->QueryLeaveState( &m_queryID ); else m_pAGState->QueryChangeInput( "Action", &m_queryID ); } } } } } void CFlowNode_AIAnim::Serialize( SActivationInfo* pActInfo, TSerialize ser ) { TBase::Serialize( pActInfo, ser ); ser.Value( "m_bStarted", m_bStarted ); ser.Value( "m_iMethod", m_iMethod ); if ( ser.IsReading() && m_pAGState != NULL ) { m_pAGState->RemoveListener( this ); m_pAGState = NULL; } } // //------------------------------------------------------------------------------------------------------------- void CFlowNode_AIAnim::GetConfiguration( SFlowNodeConfig &config ) { static const SInputPortConfig in_config[] = { InputPortConfig_Void( "sink", _HELP("for synchronization only"), _HELP("Sync") ), InputPortConfig_Void( "cancel", _HELP("cancels execution (or stops the action)") ), InputPortConfig<string>( "animstateEx_name", _HELP("name of animation to be played") ), InputPortConfig<int>( "signal", 1, _HELP("which method to use"), _HELP("Method"), _UICONFIG("enum_int:Signal=1,Action=2") ), //InputPortConfig<int>( "count", 1, _HELP("OBSOLETE PORT!!! Don't use it! Will be removed soon...") ), {0} }; static const SOutputPortConfig out_config[] = { OutputPortConfig<EntityId>( "done", _HELP("action done") ), OutputPortConfig<EntityId>( "succeed", _HELP("action done successfully") ), OutputPortConfig<EntityId>( "fail", _HELP("action failed") ), OutputPortConfig<EntityId>( "start", _HELP("activated on animation start") ), {0} }; config.sDescription = _HELP( "Plays animation" ); config.pInputPorts = in_config; config.pOutputPorts = out_config; config.nFlags |= EFLN_TARGET_ENTITY; config.SetCategory(EFLN_APPROVED); } DEF_CLONE(CFlowNode_AIAnim) // //------------------------------------------------------------------------------------------------------------- void CFlowNode_AIAnim::DoProcessEvent( EFlowEvent event, SActivationInfo* pActInfo ) { IActor* pActor = gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor( m_EntityId ); if ( pActor ) { m_pAGState = pActor->GetAnimationGraphState(); if (!m_pAGState) return; m_pAGState->AddListener( "aianim", this ); m_iMethod = GetPortInt( pActInfo, 3 ); switch ( m_iMethod ) { case 0: // forced state m_pAGState->PushForcedState( GetPortString( pActInfo, 2 ), &m_queryID ); break; case 1: // use "signal" m_pAGState->SetInput( "Signal", GetPortString( pActInfo, 2 ), &m_queryID ); break; case 2: // use "action" m_pAGState->SetInput( "Action", GetPortString( pActInfo, 2 ), &m_queryID ); break; } } else { CRY_ASSERT(0); } if (!m_bStarted) Execute( pActInfo, "ACT_ANIM" ); } // //------------------------------------------------------------------------------------------------------------- void CFlowNode_AIAnim::QueryComplete( TAnimationGraphQueryID queryID, bool succeeded ) { IEntity* pEntity = gEnv->pEntitySystem->GetEntity( m_EntityId ); if ( !pEntity ) return; if ( queryID != m_queryID ) return; IAIObject* pAI = pEntity->GetAI(); if ( succeeded || m_bStarted && m_iMethod == 2 ) { if ( !m_bStarted ) { m_bStarted = true; // if "signal" wait to leave current state // if "action" wait for input value change if ( m_iMethod <= 1 ) m_pAGState->QueryLeaveState( &m_queryID ); else m_pAGState->QueryChangeInput( "Action", &m_queryID ); // activate "Start" output port SFlowAddress start( m_nodeID, 3, true ); m_pGraph->ActivatePort( start, m_EntityId ); } else { if ( pAI ) { IPipeUser* pPipeUser = pAI->CastToIPipeUser(); if (pPipeUser) pPipeUser->RemoveSubPipe( m_GoalPipeId, true ); } if ( m_pAGState ) { m_pAGState->RemoveListener( this ); m_pAGState = NULL; m_queryID = 0; m_bStarted = false; } } } else if ( pAI ) { IPipeUser* pPipeUser = pAI->CastToIPipeUser(); if (pPipeUser) pPipeUser->CancelSubPipe( m_GoalPipeId ); } }
Attachments
FlowNodeAIAction.cpp
(150.21 KiB) Downloaded 7 times

Re: node AI:Anim

#12
I found codes for AI: Anim.
Will I add these codes, does it work?

Code: Select all

CFlowNode_AIAnim::~CFlowNode_AIAnim() { OnCancel(); } void CFlowNode_AIAnim::OnCancelPortActivated( IPipeUser* pPipeUser, SActivationInfo* pActInfo ) { if ( m_iMethod == 2 ) // is method == Action? { pPipeUser->RemoveSubPipe( m_GoalPipeId, true ); OnCancel(); // only to reuse unregistering code } else pPipeUser->CancelSubPipe( m_GoalPipeId ); } void CFlowNode_AIAnim::OnCancel() { if ( m_pAGState ) { m_pAGState->RemoveListener( this ); switch ( m_iMethod ) { case 0: if ( !m_bStarted ) m_pAGState->ClearForcedStates(); break; case 1: if ( !m_bStarted ) m_pAGState->SetInput( "Signal", "none" ); m_pAGState->Hurry(); break; case 2: m_pAGState->SetInput( "Action", "idle" ); break; } m_pAGState = NULL; m_queryID = 0; m_bStarted = false; } } void CFlowNode_AIAnim::DestroyedState(IAnimationGraphState*) { m_pAGState = NULL; m_queryID = 0; m_bStarted = false; } void CFlowNode_AIAnim::OnEntityEvent( IEntity* pEntity, SEntityEvent& event ) { TBase::OnEntityEvent( pEntity, event ); if ( event.event == ENTITY_EVENT_POST_SERIALIZE ) { if ( IActor* pActor = gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(m_EntityId) ) { m_pAGState = pActor->GetAnimationGraphState(); if ( m_pAGState != NULL ) { m_pAGState->AddListener( "aianim", this ); if ( !m_bStarted ) { IAnimationGraphState::InputID inputID = (IAnimationGraphState::InputID) -1; switch ( m_iMethod ) { case 1: // use "signal" inputID = m_pAGState->GetInputId( "Signal" ); break; case 2: // use "action" inputID = m_pAGState->GetInputId( "Action" ); break; } if ( inputID != (IAnimationGraphState::InputID) -1 ) { char inputValue[256]; m_pAGState->GetInput( inputID, inputValue ); m_pAGState->SetInput( inputID, inputValue, &m_queryID ); } } else { if ( m_iMethod <= 1 ) m_pAGState->QueryLeaveState( &m_queryID ); else m_pAGState->QueryChangeInput( "Action", &m_queryID ); } } } } } void CFlowNode_AIAnim::Serialize( SActivationInfo* pActInfo, TSerialize ser ) { TBase::Serialize( pActInfo, ser ); ser.Value( "m_bStarted", m_bStarted ); ser.Value( "m_iMethod", m_iMethod ); if ( ser.IsReading() && m_pAGState != NULL ) { m_pAGState->RemoveListener( this ); m_pAGState = NULL; } } // //------------------------------------------------------------------------------------------------------------- void CFlowNode_AIAnim::GetConfiguration( SFlowNodeConfig &config ) { static const SInputPortConfig in_config[] = { InputPortConfig_Void( "sink", _HELP("for synchronization only"), _HELP("Sync") ), InputPortConfig_Void( "cancel", _HELP("cancels execution (or stops the action)") ), InputPortConfig<string>( "animstateEx_name", _HELP("name of animation to be played") ), InputPortConfig<int>( "signal", 1, _HELP("which method to use"), _HELP("Method"), _UICONFIG("enum_int:Signal=1,Action=2") ), //InputPortConfig<int>( "count", 1, _HELP("OBSOLETE PORT!!! Don't use it! Will be removed soon...") ), {0} }; static const SOutputPortConfig out_config[] = { OutputPortConfig<EntityId>( "done", _HELP("action done") ), OutputPortConfig<EntityId>( "succeed", _HELP("action done successfully") ), OutputPortConfig<EntityId>( "fail", _HELP("action failed") ), OutputPortConfig<EntityId>( "start", _HELP("activated on animation start") ), {0} }; config.sDescription = _HELP( "Plays animation" ); config.pInputPorts = in_config; config.pOutputPorts = out_config; config.nFlags |= EFLN_TARGET_ENTITY; config.SetCategory(EFLN_APPROVED); } DEF_CLONE(CFlowNode_AIAnim) // //------------------------------------------------------------------------------------------------------------- void CFlowNode_AIAnim::DoProcessEvent( EFlowEvent event, SActivationInfo* pActInfo ) { IActor* pActor = gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor( m_EntityId ); if ( pActor ) { m_pAGState = pActor->GetAnimationGraphState(); if (!m_pAGState) return; m_pAGState->AddListener( "aianim", this ); m_iMethod = GetPortInt( pActInfo, 3 ); switch ( m_iMethod ) { case 0: // forced state m_pAGState->PushForcedState( GetPortString( pActInfo, 2 ), &m_queryID ); break; case 1: // use "signal" m_pAGState->SetInput( "Signal", GetPortString( pActInfo, 2 ), &m_queryID ); break; case 2: // use "action" m_pAGState->SetInput( "Action", GetPortString( pActInfo, 2 ), &m_queryID ); break; } } else { CRY_ASSERT(0); } if (!m_bStarted) Execute( pActInfo, "ACT_ANIM" ); } // //------------------------------------------------------------------------------------------------------------- void CFlowNode_AIAnim::QueryComplete( TAnimationGraphQueryID queryID, bool succeeded ) { IEntity* pEntity = gEnv->pEntitySystem->GetEntity( m_EntityId ); if ( !pEntity ) return; if ( queryID != m_queryID ) return; IAIObject* pAI = pEntity->GetAI(); if ( succeeded || m_bStarted && m_iMethod == 2 ) { if ( !m_bStarted ) { m_bStarted = true; // if "signal" wait to leave current state // if "action" wait for input value change if ( m_iMethod <= 1 ) m_pAGState->QueryLeaveState( &m_queryID ); else m_pAGState->QueryChangeInput( "Action", &m_queryID ); // activate "Start" output port SFlowAddress start( m_nodeID, 3, true ); m_pGraph->ActivatePort( start, m_EntityId ); } else { if ( pAI ) { IPipeUser* pPipeUser = pAI->CastToIPipeUser(); if (pPipeUser) pPipeUser->RemoveSubPipe( m_GoalPipeId, true ); } if ( m_pAGState ) { m_pAGState->RemoveListener( this ); m_pAGState = NULL; m_queryID = 0; m_bStarted = false; } } } else if ( pAI ) { IPipeUser* pPipeUser = pAI->CastToIPipeUser(); if (pPipeUser) pPipeUser->CancelSubPipe( m_GoalPipeId ); } }
waiting for an answer?

Re: node AI:Anim

#13
This node was deemed obsolete as per the reasons explained above.
You are welcome to try to create this node in a plugin in C++, though whether it works I cannot say. There may be specific functionality that needs changing, and/or refactored.
Uniflare
CRYENGINE Community Coordinator
Here to help the community and social channels grow and thrive.

My personal belongings;
Beginner Guides | My GitHub | Splash Plugin

Re: node AI:Anim

#14
This node was deemed obsolete as per the reasons explained above.
You are welcome to try to create this node in a plugin in C++, though whether it works I cannot say. There may be specific functionality that needs changing, and/or refactored.
Hi.
What is needed to create a new node?
For example, the Visual Studio version?
Do you have any plug-in documentation?
Please give a little guidance؟
cryengine 5 has little educational documentation.

Re: node AI:Anim

#15
To get started with Visual Studio you will want to check out the documentation regarding the prerequisites and installation.
http://docs.cryengine.com/pages/viewpag ... d=26216214

Creating a Flow Node in C++ is quite simple programming-wise;
Simply choose the "C++ Plugin" template.

You will want to setup your plugin class for Flow Nodes. You will want to add these MACROS to your class definition:

Code: Select all

PLUGIN_FLOWNODE_REGISTER
PLUGIN_FLOWNODE_UNREGISTER

Now you can create Flow Nodes. Check out GitHub for examples on defining a Flow Node.
There are two steps to creating a Flow Node which are:
1. Define your Flow Node class
2. Register your Flow Node class along with defining its name.

Example:

Code: Select all

#include <CryFlowGraph/IFlowBaseNode.h>

class MyFlowNode : public CFlowBaseNode<eNCT_Instanced>
{
public:
MyFlowNode(SActivationInfo* pActInfo) {};
virtual void GetMemoryUsage(ICrySizer* s) const override { s->Add(*this); }

// Allows copy-pasting in Flow Graph etc
virtual IFlowNodePtr Clone(SActivationInfo * pActInfo) override { return new MyFlowNode(pActInfo); }

// Gets the configuration (description/inputs/outputs etc)
virtual void GetConfiguration(SFlowNodeConfig& config) override
{
// Flow Node description
config.sDescription = _HELP("My flow node description");

// Basically just a label/color
config.SetCategory(EFLN_DEBUG);

// Define inputs
static const SInputPortConfig in_config[] = {
InputPortConfig_AnyType("Trigger", _HELP("Help for the input port")),
{ 0 }
};

// Define outputs
static const SOutputPortConfig out_config[] = {
OutputPortConfig<string>("Response", _HELP("The string sent after being triggered")),
{ 0 }
};

// Assign the in and out ports
config.pInputPorts = in_config;
config.pOutputPorts = out_config;
}

// Processes events sent to this node (input activation/creation etc)
virtual void ProcessEvent(EFlowEvent event, SActivationInfo* pActInfo) override
{
switch (event)
{

// When an input is activated (any input)
case eFE_Activate:
{
// If first input port is activated
if (IsPortActive(pActInfo, 0))
{
// Activate an output
ActivateOutput(pActInfo, 0, "This is the response string");
}
break;
}

}
}
};

// Register your flow node and give it a name/location
REGISTER_FLOW_NODE("Debug:SubFilter:MyFlowNode", MyFlowNode)
Uniflare
CRYENGINE Community Coordinator
Here to help the community and social channels grow and thrive.

My personal belongings;
Beginner Guides | My GitHub | Splash Plugin

Who is online

Users browsing this forum: No registered users and 0 guests

cron