## Hit indicator?

Moderators: Cry-Nic, Community Volunteers

#1

### Re: Hit indicator?

#2
Can you be a little more specific? Are you talking about hit detection per bone or exact position on mesh?
Hit detection so that you can apply damage on collision?
Uniflare
CRYENGINE Technical Community Manager
Here to help the community and social channels grow and thrive.

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

### Re: Hit indicator?

#3
Hit indicator, that thing shows damage's direction on ui. I'm wondering how to calculate and send information to action script to rotate my ui object to let player know where hit came from.

### Re: Hit indicator?

#4

Are you able to use C++?
Are you using GameSDK?
Have you setup the ActionScript functions already?

I believe the easiest option would be to create a flow graph node in C++ that is activated on player hit, which is given the player and source in code, and outputs the direction based on player rotation as a number. Though there are more than likely other methods to achieve this.
Uniflare
CRYENGINE Technical Community Manager
Here to help the community and social channels grow and thrive.

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

### Re: Hit indicator?

#5
I've got a bit understanding of c++ and action script as well.

In action script, i've done something like this by watching a video:

Code: Select all

``` var distanceX:Number = _xmouse - myObject._x; var distanceY:Number = _ymouse - myObject._y; // Store angle in angle variable var angle:Number = (Math.atan2(distanceY,distanceX) * 180 / Math.PI)+90; //Apply angle myObject._rotation = angle; ```
I got it.

But in 3d, i know that, i should consider player's position and hit's position.

By the way, i'm using gamesdk.
I looked at c++ code of entity face at flowgraph in c++ and saw somethings complex for me. But it is similar to what i'm trying to achieve.
And probably it's possible to do it in flowgraph.

### Re: Hit indicator?

#6
You can also use this Flowgraph to track where the shot comes from:

Code: Select all

```<Graph Description="" Group="FG"> <Nodes> <Node Id="985" Class="Entity:GetPos" pos="4608,2862,0"> <Inputs entityId="0" CoordSys="1"/> </Node> <Node Id="986" Class="Entity:EntityId" pos="4608,3060,0" EntityGUID="62b176c2-1b68-3824-9bf4-0f0f60f1668f"> <Inputs entityId="0"/> </Node> <Node Id="987" Class="Entity:GetPos" pos="4608,3114,0"> <Inputs entityId="0" CoordSys="1"/> </Node> <Node Id="988" Class="Time:Timer" pos="4266,3024,0"> <Inputs period="0.1" min="0" max="0" paused="0"/> </Node> <Node Id="989" Class="Vec3:FromVec3" pos="4914,2898,0"> <Inputs vec3="0,0,0"/> </Node> <Node Id="990" Class="Vec3:FromVec3" pos="4914,3150,0"> <Inputs vec3="0,0,0"/> </Node> <Node Id="991" Class="Actor:LocalPlayer" pos="4608,2826,0"> <Inputs /> </Node> <Node Id="992" Class="Math:Calculate" pos="5400,2970,0"> <Inputs Op="0" A="0" B="0"/> </Node> <Node Id="993" Class="Logic:Any" pos="6084,2970,0"> <Inputs /> </Node> <Node Id="994" Class="Math:Sub" pos="5166,3168,0"> <Inputs A="360" B="360"/> </Node> <Node Id="995" Name="Degreec_calculation_player_to_enemy." Class="_commentbox" pos="4248,2735.3701,0"> <Inputs TextSize="1" Color="0.27451,0.352941,0.705882" DisplayFilled="1" DisplayBox="1" SortPriority="16"/> <ResizeBorder X="0" Y="0" Width="2052" Height="486"/> <NodeSize Width="2052" Height="541.6073"/> </Node> <Node Id="996" Class="Math:Mod" pos="5868,2970,0"> <Inputs A="0" B="360"/> </Node> <Node Id="1033" Class="Math:Add" pos="5670,2970,0"> <Inputs A="0" B="180"/> </Node> <Node Id="1072" Name="reverse_values" Class="_comment" pos="5184,3150,0"/> <Node Id="1073" Name="rotate_180._so_enemy_is_at_0_instead_of_180" Class="_comment" pos="5598,2952,0"/> <Node Id="1075" Name="enemy" Class="_comment" pos="4626,3042,0"/> </Nodes> <Edges> <Edge nodeIn="989" nodeOut="985" portIn="vec3" portOut="Rotate" enabled="1"/> <Edge nodeIn="987" nodeOut="986" portIn="entityId" portOut="Id" enabled="1"/> <Edge nodeIn="990" nodeOut="987" portIn="vec3" portOut="Rotate" enabled="1"/> <Edge nodeIn="985" nodeOut="988" portIn="Get" portOut="out" enabled="1"/> <Edge nodeIn="987" nodeOut="988" portIn="Get" portOut="out" enabled="1"/> <Edge nodeIn="992" nodeOut="989" portIn="B" portOut="z" enabled="1"/> <Edge nodeIn="992" nodeOut="989" portIn="DoCalc" portOut="z" enabled="1"/> <Edge nodeIn="994" nodeOut="990" portIn="B" portOut="z" enabled="1"/> <Edge nodeIn="985" nodeOut="991" portIn="entityId" portOut="entityId" enabled="1"/> <Edge nodeIn="1033" nodeOut="992" portIn="A" portOut="out" enabled="1"/> <Edge nodeIn="1067" nodeOut="993" portIn="A" portOut="out" enabled="1"/> <Edge nodeIn="1067" nodeOut="993" portIn="B" portOut="out" enabled="1"/> <Edge nodeIn="1067" nodeOut="993" portIn="DoCalc" portOut="out" enabled="1"/> <Edge nodeIn="1069" nodeOut="993" portIn="A" portOut="out" enabled="1"/> <Edge nodeIn="992" nodeOut="994" portIn="A" portOut="out" enabled="1"/> <Edge nodeIn="993" nodeOut="996" portIn="in1" portOut="out" enabled="1"/> <Edge nodeIn="996" nodeOut="1033" portIn="A" portOut="out" enabled="1"/> </Edges> </Graph> ```
You can use that with the combination of the Flownode Weapon:HitInfo by putting Actor:LocalPlayer as target.

This video should give you an idea how to set it up.
https://www.cryengine.com/tutorials/des ... ll-counter

### Re: Hit indicator?

#7
Very cool. Thanks Chris.

### Re: Hit indicator?

#8
Missed this but if you are still looking for C++ addition to work with GameSDK, you can simply add a FlowGraph node that listens to Hit events. I added this node to the FlowActorNodes.cpp but anywhere else should be fine.

Code: Select all

```////////////////////////////////////////////////////////////////////////// // Player OnHit event propogator for FlowGraph ////////////////////////////////////////////////////////////////////////// class CFlowNode_ActorOnHit : public CFlowBaseNode<eNCT_Instanced>, public IHitListener { public: CFlowNode_ActorOnHit(SActivationInfo* pActInfo) { } virtual ~CFlowNode_ActorOnHit() { // safety unregister if (CGameRules* pGameRules = g_pGame->GetGameRules()) { pGameRules->RemoveHitListener(this); } } IFlowNodePtr Clone(SActivationInfo* pActInfo) { return new CFlowNode_ActorOnHit(pActInfo); } void Serialize(SActivationInfo* pActInfo, TSerialize ser) { if (ser.IsReading()) { RegisterOrUnregisterListener(pActInfo); } } enum EInputPorts { EIP_Enable = 0, }; enum EOutputPorts { EOP_AttackDegrees = 0, }; virtual void GetConfiguration(SFlowNodeConfig& config) { static const SInputPortConfig inputs[] = { InputPortConfig<bool>("Enable", false, _HELP("Enable/Disable Hit events for this node")), { 0 } }; static const SOutputPortConfig outputs[] = { OutputPortConfig<float>("Degrees", _HELP("Degrees angle from player direction to damage source")), { 0 } }; config.pInputPorts = inputs; config.pOutputPorts = outputs; config.sDescription = _HELP("Will trigger on every hit that would damage the actor. Provides degrees (clockwise) of source attacker based on player forward direction."); config.SetCategory(EFLN_ADVANCED); } virtual void ProcessEvent(EFlowEvent event, SActivationInfo* pActInfo) { switch (event) { case eFE_Initialize: m_actInfo = *pActInfo; // fall through and enable/disable listener case eFE_Activate: RegisterOrUnregisterListener(pActInfo); break; } } void RegisterOrUnregisterListener(SActivationInfo* pActInfo) { CGameRules* pGameRules = g_pGame->GetGameRules(); if (!pGameRules) { GameWarning("[flow] CFlowHitInfoNode::RegisterListener: No GameRules!"); return; } // TODO: Create a listener class to handle wether this node gets OnHit events if (GetPortBool(pActInfo, EIP_Enable)) { pGameRules->AddHitListener(this); } else { pGameRules->RemoveHitListener(this); } } // IHitListener virtual void OnHit(const HitInfo& hit) override { if (const IEntity* pTarget = gEnv->pEntitySystem->GetEntity(hit.targetId)) { if (gEnv->pGameFramework->GetClientEntityId() == pTarget->GetId()) { const IEntity* pSource = gEnv->pEntitySystem->GetEntity(hit.shooterId); // Get angles of Player Direction and Source Angle const Vec3 PlayerFwdDir = pTarget->GetForwardDir(); const Vec3 SourceFwdDir = pSource->GetWorldPos()-pTarget->GetWorldPos(); // Convert to PI clamped angles const float PlayerAtan = atan2f(PlayerFwdDir.y, PlayerFwdDir.x); const float SourceAtan = atan2f(SourceFwdDir.y, SourceFwdDir.x); // Get Angle of source based on player direction const float Direction = PlayerAtan - SourceAtan; // Convert to degrees const float Degrees = (Direction > 0 ? Direction : (2*gf_PI+ Direction)) * 360 / (2*gf_PI); ActivateOutput(&m_actInfo, EOP_AttackDegrees, Degrees); } } }; virtual void OnExplosion(const ExplosionInfo&) override {}; virtual void OnServerExplosion(const ExplosionInfo&) override {}; // ~IHitListener virtual void GetMemoryUsage(ICrySizer* s) const { s->Add(*this); } SActivationInfo m_actInfo; }; REGISTER_FLOW_NODE( "Actor:OnHit", CFlowNode_ActorOnHit );```
This way works for any entity that hits the player, you can also hook explosion with this with a trivial change also.
Uniflare
CRYENGINE Technical Community Manager
Here to help the community and social channels grow and thrive.

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

#9