News › Forums › RAIN › General Discussion and Troubleshooting › Custom Decision broken? Child nodes run even with failure
Tagged: custom decision
This topic contains 11 replies, has 2 voices, and was last updated by MikeHunt 9 months, 1 week ago.
-
AuthorPosts
-
June 24, 2022 at 8:29 am #38344
I checked with a Debug.LogError and it fails every time but the first few child nodes still play.
Any ideas?
June 24, 2022 at 9:33 am #38345Can you share the code for the Custom Decision you are using? Since it is custom, it is up to the decision to check the result of the children it runs, and it can ignore the return values if it likes.
June 24, 2022 at 10:09 am #38346Here:
using UnityEngine; using System.Collections; using System.Collections.Generic; using RAIN.Action; using RAIN.Core; [RAINDecision] public class Trip : RAINDecision { private int _lastRunning = 0; public override void Start(RAIN.Core.AI ai) { base.Start(ai); _lastRunning = 0; ai.WorkingMemory.SetItem<bool>("Tripping", false); } public override ActionResult Execute(RAIN.Core.AI ai) { ActionResult tResult = ActionResult.FAILURE; for (; _lastRunning < _children.Count; _lastRunning++) { tResult = _children[_lastRunning].Run(ai); if (tResult != ActionResult.SUCCESS) break; } if (ai.WorkingMemory.GetItem<bool>("Tripping")) return ActionResult.RUNNING; tResult = ai.WorkingMemory.GetItem<bool>("Trip") ? ActionResult.SUCCESS : ActionResult.FAILURE; if (tResult == ActionResult.SUCCESS) ai.WorkingMemory.SetItem<bool>("Tripping", true); return tResult; } public override void Stop(RAIN.Core.AI ai) { base.Stop(ai); } }
June 24, 2022 at 10:18 am #38347OK, so are the children of this node dependent on the Tripping or Trip variables in any way? Do they play out the trip action for instance?
June 24, 2022 at 10:31 am #38348To make it more clear I’ve stripped out unnecessary code:
If it fails, surely no children should run?
using UnityEngine; using System.Collections; using System.Collections.Generic; using RAIN.Action; using RAIN.Core; [RAINDecision] public class Trip : RAINDecision { private int _lastRunning = 0; public override void Start(RAIN.Core.AI ai) { base.Start(ai); _lastRunning = 0; } public override ActionResult Execute(RAIN.Core.AI ai) { ActionResult tResult = ActionResult.FAILURE; for (; _lastRunning < _children.Count; _lastRunning++) { tResult = _children[_lastRunning].Run(ai); if (tResult != ActionResult.SUCCESS) break; } return tResult; } public override void Stop(RAIN.Core.AI ai) { base.Stop(ai); } }
June 24, 2022 at 10:46 am #38350After removing the extra code, the way this Custom Decision is written says that it will start executing children until one of them returns running or failure (exactly like a sequencer). If it has no children to execute it will always return failure.
To answer your question directly: if it fails, it means it has no children, or the last child it just executed returned failure.
June 24, 2022 at 11:17 am #38355So before we go back and forth too much, I modified your original code in a way that made sense to me. Perhaps it will give you some insight to how you want to write your custom decision:
... public override ActionResult Execute(RAIN.Core.AI ai) { ActionResult tResult = ActionResult.FAILURE; // If Trip was set to true, start tripping if (ai.WorkingMemory.GetItem<bool>("Trip")) ai.WorkingMemory.SetItem<bool>("Tripping", true); // As long as tripping remains true, execute our children // like a sequencer would (which means if one of them fails // we will be done) if (ai.WorkingMemory.GetItem<bool>("Tripping")) { for (; _lastRunning < _children.Count; _lastRunning++) { tResult = _children[_lastRunning].Run(ai); if (tResult != ActionResult.SUCCESS) break; } } // And done, either we haven't been tripped, tripping is // no longer true, or our children are running or finished return tResult; } ...
So essentially this decision will always return failure if Trip isn’t set. Once Trip is set to true, it will set Tripping true and start executing children until one of them return running or failure. The Tripping variable acts a bit like a constraint, if at some point you want to stop this node from executing its children you could set Tripping to false and this node would return failure.
- This reply was modified 9 months, 2 weeks ago by Sigil. Reason: fixed comment
June 24, 2022 at 11:34 am #38357Yeah I see how the child nodes are processed now, I didn’t fully understand how the script worked, thanks!
Also is there some way to get hold the RAIN node code for integrating custom things in the future? Everything seems to be locked in DLL’s.
June 24, 2022 at 12:15 pm #38358Unfortunately the node code (and RAIN code in general) isn’t public at the moment, and there are several reasons for that, but it is besides the point. If you have questions (specific or general) on how certain nodes work or what is happening behind the scenes feel free to post here in the forums.
June 24, 2022 at 12:17 pm #38359My main issue is the timers, I’m just trying to make a script that checks forever but when it starts to run it doesn’t repeat which then breaks the timers and it also processes in sequence.
June 24, 2022 at 1:14 pm #38361I think I need a little more information on the effect you are trying to get. It’s possible that you are doing too much in one action (the checking AND running). If you split those into an expression that repeats forever and then the rest it may get what you need. Something like:
sequencer expression that checks something forever sequencer that actually runs the rest
But again, some more information, or perhaps a screen shot or pseudo code for your tree that you are working on.
EDIT: Added the code block so that actually makes sense.
June 25, 2022 at 7:34 pm #38380Thanks, I’ve split everything so repeats and non-repeats are under two difference channels under a Parallel node and now it works, yay!
Just in case anyone else has this problem, make sure that parents of the timers don’t have repeat set as well.
-
AuthorPosts
You must be logged in to reply to this topic.