Modular Behaviour Tree that has Friendly AI's Shoot Enemy while Following Player w/Flowgraph Script?

#1
Hi Everyone,

I'm working on creating a squad of 4 friendly AI that I can tell to follow me (the player) while simultaneously shoot enemy AI's.

I think this means having the Modular Behaviour Tree running parallel with the Flow Graph script, and right now it seems to choose one or the other. By that I mean, the AI will either follow me when executing the Flow Graph, or transition to combat and stop following to shoot enemies when it executes the MBT.

If anyone has any advice how to have both combat and follow at the same time it would be much appreciated! Perhaps it should all be done in one flowgraph script?

Feel free to ask any questions that may help provide better info. Posted below are of my Flowgraph and MBT. The MBT is just a slightly tweaked version of the SDK_Grunt_05.xml


Image


<BehaviorTree>

<!--
=============================================================================================================================================
SDK_Grunt_05.xml

Behavior tree that builds on top of the SDK_Grunt_04.xml.

Additions / changes:
- when entering combat, AIs now give the user a small reaction time (1-2 seconds) before starting to actually shoot at him while already moving to a good combat position
(this is to showcase a prime example of parallel behaviors)
- scripted sequences via Flow Graphs are now supported
~ scripted sequences can be either interruptible or non-interruptible (this can be specified in the "AISequence:Start" nodes inside the Flow Graph editor)
~ notice the places in the behavior tree where the interruptible and non-interruptible sequences are placed
=============================================================================================================================================
-->

<Variables>
<Variable name="HasTarget"/>
<Variable name="ExecuteSequence"/>
<Variable name="ExecuteInterruptibleSequence"/>
</Variables>

<SignalVariables>
<Signal name="OnNewAttentionTarget" variable="HasTarget" value="true"/>
<Signal name="OnNoTarget" variable="HasTarget" value="false"/>
</SignalVariables>

<Timestamps>
<Timestamp name="TargetSpotted" setOnEvent="OnEnemySeen" exclusiveTo="TargetLost"/>
<Timestamp name="TargetLost" setOnEvent="OnLostSightOfTarget" exlusiveTo="TargetSpotted"/>
<Timestamp name="GroupTargetSpotted" setOnEvent="OnGroupTargetVisual" exclusiveTo="GroupTargetLost"/>
<Timestamp name="GroupTargetLost" setOnEvent="OnGroupTargetMemory" exclusiveTo="GroupTargetSpotted"/>
<Timestamp name="EnteredCombat" setOnEvent="EnteredCombat"/>
</Timestamps>

<Root>

<Priority>

<!--
=================================================
- Scripted non-interruptible behavior (via Flow Graph)
- this node has highest priority in the BT, so no other behavior can interrupt it
- make sure to call the "ExecuteSequence" lua behavior here (and not ExecuteInterruptibleSequence)
=================================================
-->

<Case condition="ExecuteSequence">

<Sequence>

<LuaBehavior name="ExecuteSequence"/>

</Sequence>

</Case>

<!--
=================================================
Autonomous behavior
=================================================
-->

<Case>

<StateMachine>

<!--
=================================================
Idle
=================================================
-->

<State name="Idle">

<Transitions>
<Transition to="Combat" onEvent="OnEnemySeen"/>
<Transition to="Combat" onEvent="GroupMemberEnteredCombat"/>
</Transitions>

<BehaviorTree>

<Sequence>

<SetAlertness value="1"/>

<Stance name="Alerted"/>

<SuppressFailure>

<LuaGate code="return entity.PropertiesInstance.AI.bGoBackToStartOnIdle">

<Move to="InitialPosition" speed="Sprint" stance="Alerted" _startLog="moving back to initial position"/>

</LuaGate>

</SuppressFailure>

<ExecuteLua code="entity.actor:HolsterItem(false)"/>

<Priority>

<!--
=================================================
- Interruptible scripted behavior
- this node can be easily interrupted by higher-prioritized behaviors
- make sure to call the "ExecuteInterruptibleSequence" lua behavior here (and not ExecuteSequence)
=================================================
-->

<Case condition="ExecuteInterruptibleSequence">

<LuaBehavior name="ExecuteInterruptibleSequence"/>

</Case>

<Case>

<Sequence>

<!-- ensure that we also move back to our initial position after an interruptible sequence was played back -->
<SuppressFailure>

<LuaGate code="return entity.PropertiesInstance.AI.bGoBackToStartOnIdle">

<Move to="InitialPosition" speed="Sprint" stance="Relaxed" _startLog="moving back to initial position"/>

</LuaGate>

</SuppressFailure>

<Animate name="ZZ_AI_idleBreak" loop="1"/>

</Sequence>

</Case>

</Priority>

</Sequence>

</BehaviorTree>

</State>

<!--
=================================================
Combat
=================================================
-->

<State name="Combat">

<Transitions>
<Transition to="ApproachAndInspectLastKnownPlayerPosition" onEvent="GoTo_ApproachAndInspectLastKnownPlayerPosition"/>
</Transitions>

<BehaviorTree>

<Sequence>

<Log message="Now I should fight you!"/>

<SetAlertness value="2"/>

<Stance name="Alerted"/>

<ExecuteLua code="entity:SelectPrimaryWeapon()"/>

<Communicate name="TargetSpottedWhileSearching" channel="Reaction" expirity="1.0" waitUntilFinished="0" />

<Signal name="EnteredCombat"/>

<Signal name="GroupMemberEnteredCombat" filter="Group"/>

<!--
=================================================
main combat loop
=================================================
-->
<Loop _startLog="main combat loop">

<Sequence>

<Selector>

<!--
=================================================
cover combat
=================================================
-->

<Sequence>

<Selector>

<AssertLua code="return (AI.IsInCover(entity.id) and not AI.IsCoverCompromised(entity.id)) "/>

<Sequence>

<Log message="trying to find cover"/>

<QueryTPS name="SDKGrunt_CoverToShootFrom" register="Cover"/>

<Log message="moving to found cover"/>

<!-- move to cover; while doing so, start shooting after a small random time of 1-2seconds -->
<Parallel successMode="any">

<Move to="Cover" speed="Run" stance="Stand" fireMode="Off" avoidDangers="1"/>

<Sequence>

<!-- wait between 1 and 2 seconds before shooting -->
<SuppressFailure>

<IfTime since="EnteredCombat" isLessThan="2.0">

<Sequence>

<WaitUntilTime since="EnteredCombat" isMoreThan="1.0"/>

<Wait duration="0.0" variation="1.0"/>

</Sequence>

</IfTime>

</SuppressFailure>

<Shoot at="Target" fireMode="Burst" stance="Alerted" duration="999"/>

</Sequence>

</Parallel>

</Sequence>

</Selector>

<Log message="+++ shooting from cover BEGIN +++"/>

<ShootFromCover duration="2.0" fireMode="Burst" aimObstructedTimeout="1.0"/>

<Log message="--- shooting from cover END ---"/>

<AdjustCoverStance duration="3.0" />

</Sequence>

<!--
=================================================
open combat
=================================================
-->

<Sequence>

<Log message="open combat"/>

<SuppressFailure>

<Sequence>

<QueryTPS name="SDKGrunt_OpenCombat" register="RefPoint"/>

<!-- move to the queried combat position; while doing so, start shooting after a small random time of 1-2seconds -->
<Parallel successMode="any">

<Move to="RefPoint" speed="Run" stance="Alerted" fireMode="Off"/>

<Sequence>

<!-- wait between 1 and 2 seconds before shooting -->
<SuppressFailure>

<IfTime since="EnteredCombat" isLessThan="2.0">

<Sequence>

<WaitUntilTime since="EnteredCombat" isMoreThan="1.0"/>

<Wait duration="0.0" variation="1.0"/>

</Sequence>

</IfTime>

</SuppressFailure>

<Shoot at="Target" fireMode="Burst" stance="Alerted" duration="999"/>

</Sequence>

</Parallel>

</Sequence>

</SuppressFailure>

<Shoot at="Target" fireMode="Burst" stance="Stand" duration="2.0" _startLog="starting to shoot"/>

</Sequence>

</Selector>

<!-- transition to "ApproachAndInspectLastKnownPlayerPosition" after the target hasn't been seen for some seconds -->
<SuppressFailure>

<Selector>

<LuaGate code="return AI.GetGroupOf(entity.id) == 0;">

<IfTime since="TargetLost" isMoreThan="5">

<SendTransitionSignal name="GoTo_ApproachAndInspectLastKnownPlayerPosition"/>

</IfTime>

</LuaGate>

<LuaGate code="return AI.GetGroupOf(entity.id) ~= 0;">

<IfTime since="GroupTargetLost" isMoreThan="5">

<SendTransitionSignal name="GoTo_ApproachAndInspectLastKnownPlayerPosition"/>

</IfTime>

</LuaGate>

</Selector>

</SuppressFailure>

</Sequence>

</Loop>

</Sequence>

</BehaviorTree>

</State>

<!--
=================================================
ApproachAndInspectLastKnownPlayerPosition
=================================================
-->

<State name="ApproachAndInspectLastKnownPlayerPosition">

<Transitions>
<Transition to="Idle" onEvent="GoTo_Idle"/>
<Transition to="Combat" onEvent="OnEnemySeen"/>
<Transition to="Combat" onEvent="OnGroupTargetVisual"/>
<Transition to="Combat" onEvent="GroupMemberEnteredCombat"/>
</Transitions>

<BehaviorTree>

<Sequence>

<SuppressFailure>

<Move to="Target" speed="Sprint" stance="Alerted" fireMode="Off" avoidDangers="0" stopWithinDistance="100"/>

</SuppressFailure>

<Parallel successMode="any">

<Animate name="AI_SearchLookAround" loop="1"/>

<SuppressFailure>
<Timeout duration=".1"/>
</SuppressFailure>

</Parallel>

<SendTransitionSignal name="GoTo_Idle"/>

</Sequence>

</BehaviorTree>

</State>

</StateMachine>

</Case>

</Priority>

</Root>

</BehaviorTree>

Re: Modular Behaviour Tree that has Friendly AI's Shoot Enemy while Following Player w/Flowgraph Script?

#2
You could use AIAssignments:CombatMove
I have noticed it only working while in combat, so here is what I did:

Image

Code: Select all

<Graph Description="" Group="Friend"> <Nodes> <Node Id="11" Class="AIAssignments:CombatMove" pos="234,1026,0" GraphEntity="0"> <Inputs entityId="0" Position="0,0,0" UseCover="0"/> </Node> <Node Id="59" Class="AISequence:Start" pos="720,65.436096,0" GraphEntity="0"> <Inputs entityId="0" Interruptible="1" ResumeAfterInterruption="1"/> </Node> <Node Id="60" Class="AISequence:End" pos="1422,72,0" GraphEntity="0"> <Inputs entityId="0"/> </Node> <Node Id="61" Class="AISequence:Move" pos="1044,65.436096,0" GraphEntity="0"> <Inputs entityId="0" Speed="2" Stance="0" DestinationEntity="0" Position="0,0,0" Direction="0,0,0" EndDistance="5"/> </Node> <Node Id="62" Class="Entity:GetPos" pos="1044,270,0"> <Inputs entityId="0" CoordSys="1"/> </Node> <Node Id="63" Class="Actor:LocalPlayer" pos="1044,234,0"> <Inputs /> </Node> <Node Id="65" Class="Logic:Any" pos="306,126,0" InHideMask="1017"> <Inputs /> </Node> <Node Id="66" Name="Follow_player" Class="_commentbox" pos="-144,-9.3816471,0"> <Inputs TextSize="1" Color="0.27451,0.352941,0.705882" DisplayFilled="1" DisplayBox="1" SortPriority="16"/> <ResizeBorder X="0" Y="0" Width="1764" Height="504"/> <NodeSize Width="1764" Height="559.32721"/> </Node> <Node Id="67" Name="Use_gate_to_enable/disable_following_player" Class="_comment" pos="414,90,0"/> <Node Id="69" Class="Logic:Gate" pos="486,126,0"> <Inputs Closed="0"/> </Node> <Node Id="70" Name="Start_following_player_for_the_first_time" Class="_comment" pos="-126,108,0"/> <Node Id="76" Class="Logic:Any" pos="1494,432,0" InHideMask="1022"> <Inputs /> </Node> <Node Id="78" Class="Logic:Any" pos="198,432,0" InHideMask="1023" OutHideMask="1"> <Inputs /> </Node> <Node Id="1083" Class="Time:Delay" pos="990,738,0"> <Inputs delay="0.5" resetOnInput="0"/> </Node> <Node Id="1094" Class="AI:BehaviorTree" pos="-90,360,0" GraphEntity="0"> <Inputs entityId="0"/> </Node> <Node Id="1104" Class="AI:BodyCount" pos="-90,216,0"> <Inputs /> </Node> <Node Id="1111" Class="Time:Delay" pos="-90,414,0"> <Inputs delay="1" resetOnInput="0"/> </Node> <Node Id="1113" Name="Reset_behaviour_tree_after_kill" Class="_comment" pos="-90,198,0"/> <Node Id="1116" Name="(still_needs_an_extra_input_signal)" Class="_comment" pos="450,108,0"/> <Node Id="1118" Class="Logic:Any" pos="0,126,0" InHideMask="1022" OutHideMask="1"> <Inputs /> </Node> <Node Id="1143" Class="Game:Start" pos="-414,126,0"> <Inputs InGame="1" InEditor="1"/> </Node> <Node Id="1144" Class="Time:Delay" pos="-216,126,0"> <Inputs delay="1" resetOnInput="0"/> </Node> <Node Id="1179" Class="Time:Timer" pos="-288,1080,0"> <Inputs period="1" min="0" max="0" paused="0"/> </Node> <Node Id="1181" Class="Actor:LocalPlayer" pos="-36,1026,0"> <Inputs /> </Node> <Node Id="1182" Class="Entity:GetPos" pos="-36,1062,0"> <Inputs entityId="0" CoordSys="1"/> </Node> <Node Id="1184" Class="Time:Delay" pos="-90,288,0"> <Inputs delay="1" resetOnInput="0"/> </Node> <Node Id="1214" Class="Entity:CheckDistance" pos="-54,612,0"> <Inputs entityId="0" MinDistance="0" MaxDistance="0" Entity1="0" Entity2="0" Entity3="0" Entity4="0" Entity5="0" Entity6="0" Entity7="0" Entity8="0" Entity9="0" Entity10="0" Entity11="0" Entity12="0" Entity13="0" Entity14="0" Entity15="0" Entity16="0"/> </Node> <Node Id="1216" Class="Actor:LocalPlayer" pos="-54,576,0"> <Inputs /> </Node> <Node Id="1218" Class="Time:Timer" pos="-360,630,0"> <Inputs period="0.1" min="0" max="0" paused="0"/> </Node> <Node Id="1220" Class="Entity:EntityId" pos="-216,720,0" GraphEntity="0"> <Inputs entityId="0"/> </Node> <Node Id="1224" Class="Math:InRange" pos="234,648,0"> <Inputs In="0" Min="0" Max="5"/> </Node> <Node Id="1228" Class="Mission:GameTokenSet" pos="414,702,0"> <Inputs gametoken_Token="Near_Player" Value="0"/> </Node> <Node Id="1243" Class="Mission:GameTokenCheck" pos="1062,522,0"> <Inputs gametoken_Token="Near_Player" CheckValue="1"/> </Node> <Node Id="1245" Class="Logic:Any" pos="828,522,0"> <Inputs /> </Node> <Node Id="1246" Class="Mission:GameTokenSet" pos="414,630,0"> <Inputs gametoken_Token="Near_Player" Value="1"/> </Node> <Node Id="1249" Name="FriendAI" Class="_comment" pos="-180,378,0"/> <Node Id="1250" Name="FriendAI" Class="_comment" pos="720,36,0"/> <Node Id="1251" Name="FriendAI" Class="_comment" pos="1044,36,0"/> <Node Id="1252" Name="FriendAI" Class="_comment" pos="1422,36,0"/> <Node Id="1253" Name="Near_Player_Bool" Class="_comment" pos="414,612,0"/> <Node Id="1254" Name="Near_Player_Bool" Class="_comment" pos="414,774,0"/> <Node Id="1255" Name="Near_Player_Bool" Class="_comment" pos="1062,612,0"/> </Nodes> <Edges> <Edge nodeIn="61" nodeOut="59" portIn="Start" portOut="Link" enabled="1"/> <Edge nodeIn="76" nodeOut="60" portIn="in1" portOut="Done" enabled="1"/> <Edge nodeIn="60" nodeOut="61" portIn="End" portOut="Done" enabled="1"/> <Edge nodeIn="61" nodeOut="62" portIn="Position" portOut="Pos" enabled="1"/> <Edge nodeIn="62" nodeOut="63" portIn="entityId" portOut="entityId" enabled="1"/> <Edge nodeIn="69" nodeOut="65" portIn="In" portOut="out" enabled="1"/> <Edge nodeIn="59" nodeOut="69" portIn="Start" portOut="Out" enabled="1"/> <Edge nodeIn="62" nodeOut="69" portIn="Get" portOut="Out" enabled="1"/> <Edge nodeIn="1245" nodeOut="76" portIn="in1" portOut="out" enabled="1"/> <Edge nodeIn="65" nodeOut="78" portIn="in2" portOut="out" enabled="1"/> <Edge nodeIn="1245" nodeOut="1083" portIn="in2" portOut="out" enabled="1"/> <Edge nodeIn="1111" nodeOut="1094" portIn="in" portOut="Done" enabled="1"/> <Edge nodeIn="1184" nodeOut="1104" portIn="in" portOut="Total" enabled="1"/> <Edge nodeIn="65" nodeOut="1111" portIn="in3" portOut="out" enabled="1"/> <Edge nodeIn="65" nodeOut="1118" portIn="in1" portOut="out" enabled="1"/> <Edge nodeIn="1104" nodeOut="1118" portIn="Enable" portOut="out" enabled="1"/> <Edge nodeIn="1144" nodeOut="1143" portIn="in" portOut="output" enabled="1"/> <Edge nodeIn="1118" nodeOut="1144" portIn="in1" portOut="out" enabled="1"/> <Edge nodeIn="1182" nodeOut="1179" portIn="Get" portOut="out" enabled="1"/> <Edge nodeIn="1182" nodeOut="1181" portIn="entityId" portOut="entityId" enabled="1"/> <Edge nodeIn="11" nodeOut="1182" portIn="Position" portOut="Pos" enabled="1"/> <Edge nodeIn="11" nodeOut="1182" portIn="Set" portOut="Pos" enabled="1"/> <Edge nodeIn="1094" nodeOut="1184" portIn="Reset" portOut="out" enabled="1"/> <Edge nodeIn="1224" nodeOut="1214" portIn="In" portOut="NearEntityDist" enabled="1"/> <Edge nodeIn="1214" nodeOut="1216" portIn="entityId" portOut="entityId" enabled="1"/> <Edge nodeIn="1214" nodeOut="1218" portIn="Check" portOut="out" enabled="1"/> <Edge nodeIn="1214" nodeOut="1220" portIn="Entity1" portOut="Id" enabled="1"/> <Edge nodeIn="1228" nodeOut="1224" portIn="Trigger" portOut="false" enabled="1"/> <Edge nodeIn="1246" nodeOut="1224" portIn="Trigger" portOut="true" enabled="1"/> <Edge nodeIn="78" nodeOut="1243" portIn="in1" portOut="False" enabled="1"/> <Edge nodeIn="1083" nodeOut="1243" portIn="in" portOut="True" enabled="1"/> <Edge nodeIn="1243" nodeOut="1245" portIn="Trigger" portOut="out" enabled="1"/> </Edges> </Graph>

It's not ideal, more of a quick and dirty way.
Enjoy!

Re: Modular Behaviour Tree that has Friendly AI's Shoot Enemy while Following Player w/Flowgraph Script?

#4
You could use AIAssignments:CombatMove
I have noticed it only working while in combat, so here is what I did:

Image

Code: Select all

<Graph Description="" Group="Friend"> <Nodes> <Node Id="11" Class="AIAssignments:CombatMove" pos="234,1026,0" GraphEntity="0"> <Inputs entityId="0" Position="0,0,0" UseCover="0"/> </Node> <Node Id="59" Class="AISequence:Start" pos="720,65.436096,0" GraphEntity="0"> <Inputs entityId="0" Interruptible="1" ResumeAfterInterruption="1"/> </Node> <Node Id="60" Class="AISequence:End" pos="1422,72,0" GraphEntity="0"> <Inputs entityId="0"/> </Node> <Node Id="61" Class="AISequence:Move" pos="1044,65.436096,0" GraphEntity="0"> <Inputs entityId="0" Speed="2" Stance="0" DestinationEntity="0" Position="0,0,0" Direction="0,0,0" EndDistance="5"/> </Node> <Node Id="62" Class="Entity:GetPos" pos="1044,270,0"> <Inputs entityId="0" CoordSys="1"/> </Node> <Node Id="63" Class="Actor:LocalPlayer" pos="1044,234,0"> <Inputs /> </Node> <Node Id="65" Class="Logic:Any" pos="306,126,0" InHideMask="1017"> <Inputs /> </Node> <Node Id="66" Name="Follow_player" Class="_commentbox" pos="-144,-9.3816471,0"> <Inputs TextSize="1" Color="0.27451,0.352941,0.705882" DisplayFilled="1" DisplayBox="1" SortPriority="16"/> <ResizeBorder X="0" Y="0" Width="1764" Height="504"/> <NodeSize Width="1764" Height="559.32721"/> </Node> <Node Id="67" Name="Use_gate_to_enable/disable_following_player" Class="_comment" pos="414,90,0"/> <Node Id="69" Class="Logic:Gate" pos="486,126,0"> <Inputs Closed="0"/> </Node> <Node Id="70" Name="Start_following_player_for_the_first_time" Class="_comment" pos="-126,108,0"/> <Node Id="76" Class="Logic:Any" pos="1494,432,0" InHideMask="1022"> <Inputs /> </Node> <Node Id="78" Class="Logic:Any" pos="198,432,0" InHideMask="1023" OutHideMask="1"> <Inputs /> </Node> <Node Id="1083" Class="Time:Delay" pos="990,738,0"> <Inputs delay="0.5" resetOnInput="0"/> </Node> <Node Id="1094" Class="AI:BehaviorTree" pos="-90,360,0" GraphEntity="0"> <Inputs entityId="0"/> </Node> <Node Id="1104" Class="AI:BodyCount" pos="-90,216,0"> <Inputs /> </Node> <Node Id="1111" Class="Time:Delay" pos="-90,414,0"> <Inputs delay="1" resetOnInput="0"/> </Node> <Node Id="1113" Name="Reset_behaviour_tree_after_kill" Class="_comment" pos="-90,198,0"/> <Node Id="1116" Name="(still_needs_an_extra_input_signal)" Class="_comment" pos="450,108,0"/> <Node Id="1118" Class="Logic:Any" pos="0,126,0" InHideMask="1022" OutHideMask="1"> <Inputs /> </Node> <Node Id="1143" Class="Game:Start" pos="-414,126,0"> <Inputs InGame="1" InEditor="1"/> </Node> <Node Id="1144" Class="Time:Delay" pos="-216,126,0"> <Inputs delay="1" resetOnInput="0"/> </Node> <Node Id="1179" Class="Time:Timer" pos="-288,1080,0"> <Inputs period="1" min="0" max="0" paused="0"/> </Node> <Node Id="1181" Class="Actor:LocalPlayer" pos="-36,1026,0"> <Inputs /> </Node> <Node Id="1182" Class="Entity:GetPos" pos="-36,1062,0"> <Inputs entityId="0" CoordSys="1"/> </Node> <Node Id="1184" Class="Time:Delay" pos="-90,288,0"> <Inputs delay="1" resetOnInput="0"/> </Node> <Node Id="1214" Class="Entity:CheckDistance" pos="-54,612,0"> <Inputs entityId="0" MinDistance="0" MaxDistance="0" Entity1="0" Entity2="0" Entity3="0" Entity4="0" Entity5="0" Entity6="0" Entity7="0" Entity8="0" Entity9="0" Entity10="0" Entity11="0" Entity12="0" Entity13="0" Entity14="0" Entity15="0" Entity16="0"/> </Node> <Node Id="1216" Class="Actor:LocalPlayer" pos="-54,576,0"> <Inputs /> </Node> <Node Id="1218" Class="Time:Timer" pos="-360,630,0"> <Inputs period="0.1" min="0" max="0" paused="0"/> </Node> <Node Id="1220" Class="Entity:EntityId" pos="-216,720,0" GraphEntity="0"> <Inputs entityId="0"/> </Node> <Node Id="1224" Class="Math:InRange" pos="234,648,0"> <Inputs In="0" Min="0" Max="5"/> </Node> <Node Id="1228" Class="Mission:GameTokenSet" pos="414,702,0"> <Inputs gametoken_Token="Near_Player" Value="0"/> </Node> <Node Id="1243" Class="Mission:GameTokenCheck" pos="1062,522,0"> <Inputs gametoken_Token="Near_Player" CheckValue="1"/> </Node> <Node Id="1245" Class="Logic:Any" pos="828,522,0"> <Inputs /> </Node> <Node Id="1246" Class="Mission:GameTokenSet" pos="414,630,0"> <Inputs gametoken_Token="Near_Player" Value="1"/> </Node> <Node Id="1249" Name="FriendAI" Class="_comment" pos="-180,378,0"/> <Node Id="1250" Name="FriendAI" Class="_comment" pos="720,36,0"/> <Node Id="1251" Name="FriendAI" Class="_comment" pos="1044,36,0"/> <Node Id="1252" Name="FriendAI" Class="_comment" pos="1422,36,0"/> <Node Id="1253" Name="Near_Player_Bool" Class="_comment" pos="414,612,0"/> <Node Id="1254" Name="Near_Player_Bool" Class="_comment" pos="414,774,0"/> <Node Id="1255" Name="Near_Player_Bool" Class="_comment" pos="1062,612,0"/> </Nodes> <Edges> <Edge nodeIn="61" nodeOut="59" portIn="Start" portOut="Link" enabled="1"/> <Edge nodeIn="76" nodeOut="60" portIn="in1" portOut="Done" enabled="1"/> <Edge nodeIn="60" nodeOut="61" portIn="End" portOut="Done" enabled="1"/> <Edge nodeIn="61" nodeOut="62" portIn="Position" portOut="Pos" enabled="1"/> <Edge nodeIn="62" nodeOut="63" portIn="entityId" portOut="entityId" enabled="1"/> <Edge nodeIn="69" nodeOut="65" portIn="In" portOut="out" enabled="1"/> <Edge nodeIn="59" nodeOut="69" portIn="Start" portOut="Out" enabled="1"/> <Edge nodeIn="62" nodeOut="69" portIn="Get" portOut="Out" enabled="1"/> <Edge nodeIn="1245" nodeOut="76" portIn="in1" portOut="out" enabled="1"/> <Edge nodeIn="65" nodeOut="78" portIn="in2" portOut="out" enabled="1"/> <Edge nodeIn="1245" nodeOut="1083" portIn="in2" portOut="out" enabled="1"/> <Edge nodeIn="1111" nodeOut="1094" portIn="in" portOut="Done" enabled="1"/> <Edge nodeIn="1184" nodeOut="1104" portIn="in" portOut="Total" enabled="1"/> <Edge nodeIn="65" nodeOut="1111" portIn="in3" portOut="out" enabled="1"/> <Edge nodeIn="65" nodeOut="1118" portIn="in1" portOut="out" enabled="1"/> <Edge nodeIn="1104" nodeOut="1118" portIn="Enable" portOut="out" enabled="1"/> <Edge nodeIn="1144" nodeOut="1143" portIn="in" portOut="output" enabled="1"/> <Edge nodeIn="1118" nodeOut="1144" portIn="in1" portOut="out" enabled="1"/> <Edge nodeIn="1182" nodeOut="1179" portIn="Get" portOut="out" enabled="1"/> <Edge nodeIn="1182" nodeOut="1181" portIn="entityId" portOut="entityId" enabled="1"/> <Edge nodeIn="11" nodeOut="1182" portIn="Position" portOut="Pos" enabled="1"/> <Edge nodeIn="11" nodeOut="1182" portIn="Set" portOut="Pos" enabled="1"/> <Edge nodeIn="1094" nodeOut="1184" portIn="Reset" portOut="out" enabled="1"/> <Edge nodeIn="1224" nodeOut="1214" portIn="In" portOut="NearEntityDist" enabled="1"/> <Edge nodeIn="1214" nodeOut="1216" portIn="entityId" portOut="entityId" enabled="1"/> <Edge nodeIn="1214" nodeOut="1218" portIn="Check" portOut="out" enabled="1"/> <Edge nodeIn="1214" nodeOut="1220" portIn="Entity1" portOut="Id" enabled="1"/> <Edge nodeIn="1228" nodeOut="1224" portIn="Trigger" portOut="false" enabled="1"/> <Edge nodeIn="1246" nodeOut="1224" portIn="Trigger" portOut="true" enabled="1"/> <Edge nodeIn="78" nodeOut="1243" portIn="in1" portOut="False" enabled="1"/> <Edge nodeIn="1083" nodeOut="1243" portIn="in" portOut="True" enabled="1"/> <Edge nodeIn="1243" nodeOut="1245" portIn="Trigger" portOut="out" enabled="1"/> </Edges> </Graph>

It's not ideal, more of a quick and dirty way.
Enjoy!
Thanks Chris, but mentioning "it eats much performance" would be good.

Who is online

Users browsing this forum: No registered users and 2 guests

cron