News Forums RAIN General Discussion and Troubleshooting Custom Decision broken? Child nodes run even with failure

This topic contains 11 replies, has 2 voices, and was last updated by  MikeHunt 9 months, 1 week ago.

Viewing 12 posts - 1 through 12 (of 12 total)
  • Author
    Posts
  • #38344

    MikeHunt
    Participant

    I checked with a Debug.LogError and it fails every time but the first few child nodes still play.

    Any ideas?

    #38345

    Sigil
    Keymaster

    Can 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.

    #38346

    MikeHunt
    Participant

    Here:

    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);
        }
    }
    #38347

    Sigil
    Keymaster

    OK, 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?

    #38348

    MikeHunt
    Participant

    To 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);
        }
    }
    #38350

    Sigil
    Keymaster

    After 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.

    #38355

    Sigil
    Keymaster

    So 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
    #38357

    MikeHunt
    Participant

    Yeah 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.

    #38358

    Sigil
    Keymaster

    Unfortunately 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.

    #38359

    MikeHunt
    Participant

    My 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.

    #38361

    Sigil
    Keymaster

    I 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.

    #38380

    MikeHunt
    Participant

    Thanks, 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.

Viewing 12 posts - 1 through 12 (of 12 total)

You must be logged in to reply to this topic.