News Forums RAIN General Discussion and Troubleshooting Expression in Custom Action not valid in code

This topic contains 8 replies, has 2 voices, and was last updated by  CodersExpo 1 year, 7 months ago.

Viewing 9 posts - 1 through 9 (of 9 total)
  • Author
    Posts
  • #13076

    yardGamer
    Participant

    Hello All,
    I Have a custom action that I am using in a behavior tree that I would like to pass in a Vector3 parameter. Based on what I read on these forums, I created a public Expression variable in my Custom Action class so the expression would appear in the behavior tree- -it does-Woot! However, when I put the name of a Vector3 variable in the expression field of the Custom Action in the Behavior Tree and try to evaluate that expression at run time, IsValid is false for the expression variable.

    So lets say my expression field in the CustomAction is called “centerPoint”, I put the name of a Vector3 variable that is in AI.WorkingMemory in the field, so when the Action is called, the value of that variable will be used. I want to make this custom action generic so I can use in several places in the Behavior Tree.

    Here is the code in the CustomAction class

    	public Expression centerPoint;
    	Vector3 centerPointVal;
    ...
    	centerPoint = new Expression();
    	centerPointVal = Vector3.zero;
    ...
        public override ActionResult Execute(AI ai)
        {
    		if( centerPoint.IsValid )
                        centerPointVal = centerPoint.Evaluate(ai.DeltaTime, ai.WorkingMemory).GetValue<Vector3>();
    ...
         <add random offset then use centerPointVal>
    

    The problem is the centerPoint.IsValid is never true. If I remove the condition, then the evaluation returns a zero vector.
    From what I read in previous posts this should work. Can anyone help with the proper way to pass in parameter into a CustomAction from the Behavior Tree?

    #13207

    CodersExpo
    Participant

    If I understand you correctly….”Can anyone help with the proper way to pass in parameter into a CustomAction from the Behavior Tree?”

    This is specific to what I think your trying to do.

    1. In your BT, add an evaluation node. Name it and add the evaluation expression CenterPoint = true
    2. In the ai rig add two variables. The first is a bool named CenterPoint and leave this unchecked for false. The second variable is a Vector3 named it CenterPointValue and it’s default is vector3.zero.
    3. In your custom action node following the eval node, the code might look like this:

    //The expression (in step 1 above) just switched it to true
    if(ai.WorkingMemory.GetItem<bool>(“CenterPoint”))
    {
    //Set the value of your vector3 variable
    ai.WorkingMemory.SetItem<Vector3>(“CenterPointValue”, new Vector3(10f,0f,15f));
    }

    Hope this helps.

    #13596

    yardGamer
    Participant

    This is not quite the problem. I would like to pass a parameter into my CustomAction from the behavior tree. I read that the way do to do this was to use a public expression variable in the CustomAction class then parse the value of the expression in the CustomAction start() or update() method.

    I realize that an alternate method to get a value from the BehaviorTree into the CustomAction is to use a WorkingMemory variable, however, it would be more intuitive for my designer to pass a parameter to the CustomAction instead of setting a WorkingMemory variable prior to calling the CustomAction. I want to know if what I read abut using a public expression variable to pass parameters was indeed correct, and if so, why its not working for me. My problem with this method is that when I try to parse the expression containing the variable parameter, it is showing as IsValid=false and the value parsed is zero. The expression variable I want to pass in is a Vector3 so in the Behavior tree I am placing the unquoted name of a memory variable in the field in the BehaviorTree.

    eg: I have a workingmemory variable called BallSpawnPosition and the name of my public Expression variable in my CustomAction is called centerPoint. I want to pass BallSpawnPosition into my CustomMoveTo action as the position for the AI to move to so I enter BallSpawnPosition in the field called centerPoint in the CustomMoveTo action in the behavior tree since I figured the builtin MoveTo action does something similar. However, when I parse the centerPoint Expression variable in code, it is no valid and I cannot get the correct value of it.

    #13608

    CodersExpo
    Participant

    Well still not 100% clear…”I would like to pass a parameter into my CustomAction from the behavior tree”. Try this, if you add a custom action node in your behavior tree and you want to list some variable fields on this node that can be used in your script:
    .
    .

    using RAIN.Representation;
    [RAINAction]
    public class YourCustomAction: RAINAction
    {
    	public Expression centerPoint;
    	private Vector3 _ballSpawnPosition;
        public Test()
        {
            actionName = "YourCustomAction";
        }
        public override void Start(AI ai)
        {
            _ballSpawnPosition = centerPoint.Evaluate(ai.DeltaTime, ai.WorkingMemory).GetValue<Vector3>();
            base.Start(ai);
        }

    …omitted the rest for brevity. Check the action node now. Is this what you need?

    Now you can create a vector3 variable in the AIRig memory element. Let’s call it ballspawn and give it a value 1,2,3. Add this ‘ballspawn’ into the customaction variable field you just created within the behavior tree. You should add a break point in the script and run it. Do you see the value?

    Now you can do the same by setting the working memory variable from the BT or your script as we discussed in our last thread. You should also be able to simply set up a detect node or move node and use that variable too. So for example, when you detect an object, the detect node allows you to set the aspect or form variable name. Use that same variable name in the CustomAction field. Hope this makes sense and helps.

    • This reply was modified 1 year, 7 months ago by  CodersExpo.
    • This reply was modified 1 year, 7 months ago by  CodersExpo.
    #13615

    CodersExpo
    Participant

    Also, you can drop centerPoint = new Expression();
    ..you shouldn’t have to new up anything…that will be done at centerPoint.Evaluate

    #13616

    CodersExpo
    Participant

    So…everything above was off the top of my head. So I created a example for myself just to be sure…

    I created a simple BT

    BT
       PAR
         detect (Repeat=Forever, Sensor="eyes", Aspect="aObject", Form Variable= varObject)
         SEQ
           CustomAction (centerPoint=varObject)

    The code I provided above in my last post is correct. I can get the objects vector3 position using small modification…

    using RAIN.Representation;
    [RAINAction]
    public class Test : RAINAction
    {
    	public Expression centerPoint;
    	private GameObject _ballSpawnPosition;
        public Test()
        {
            actionName = "Test";
        }
        public override void Start(AI ai)
        {
              if(centerPoint.IsValid){
    		_ballSpawnPosition = centerPoint.Evaluate(ai.DeltaTime, ai.WorkingMemory).GetValue<GameObject>();
    		Debug.Log(_ballSpawnPosition.transform.position);//Get the position of the object variable
    		Debug.Log(ai.Senses.GetSensor("eyes").Matches[0].Position);//Is the variable position the same for the object being sensed
              }
            base.Start(ai);
        }

    Hope this helps 😉

    • This reply was modified 1 year, 7 months ago by  CodersExpo.
    • This reply was modified 1 year, 7 months ago by  CodersExpo.
    #13767

    CodersExpo
    Participant

    Have you tried these two scenarios? One using a AIRig memory vector3 variable and the other using a detected node variable? I was able to get the values. Am I still missing the point :-(

    #14010

    yardGamer
    Participant

    I got this working now-Thanks for you help. I changed a few things based on your example, primarily removing this
    re-allocation of the Expression variable in the Start function:

    centerPoint = new Expression();

    I can now get my expressions as Vector and floats. Here the code that is now working.

    
    public class AIChooseWanderLocation : RAINAction
    {	
            public Expression centerPoint;
    	public Expression rangeXExpr;
    	public Expression rangeZExpr;
    .
    .
    .
    public override void Start(AI ai)
    {
      if( centerPoint.IsValid ){		
        centerPointVal = centerPoint.Evaluate(ai.DeltaTime, ai.WorkingMemory).GetValue<Vector3>();
        if( rangeXExpr.IsValid )
          rangeX = rangeXExpr.Evaluate(ai.DeltaTime, ai.WorkingMemory).GetValue<float>();
        if( rangeZExpr.IsValid )
         rangeZ = rangeZExpr.Evaluate(ai.DeltaTime, ai.WorkingMemory).GetValue<float>();
        Debug.Log ( "Choose Wander Range" + rangeX +" ," + rangeZ + " Center:" + centerPointVal );
    }
    
    • This reply was modified 1 year, 7 months ago by  yardGamer.
    #14026

    CodersExpo
    Participant

    Saweeeeet 😉 Happy to help.

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

You must be logged in to reply to this topic.