News Forums RAIN General Discussion and Troubleshooting Assigning variables for custom actions

This topic contains 14 replies, has 7 voices, and was last updated by  justinliebregts 3 years ago.

Viewing 15 posts - 1 through 15 (of 15 total)
  • Author
    Posts
  • #4745

    Sprakle
    Participant

    Is there a way to assign individual variables for a custom behaviour tree action? Similar to assigning variables in the Unity inspector for a script component.

    I cannot simply define global variables in the AI memory, since I have some custom actions that are used more than once on the tree, and they must each be given different values.

    Thanks, and keep up the great work!

    #4759

    Aaron Mueller
    Participant

    Sprakle,

    I created a custom C# script and attached it to the avatar (in RAIN this would be the parent game object of the AI child now called AIRig).

    Then, in your custom script, make public variables if you want to expose them to the editor.

    In my case, I created a script that I used to set a game object to act as the transform (location) of a destination. I used invisible game objects to represent my desired location.

    Then in your Custom Action for your behavior tree, you link a private variable something like this:

    CustomScript myScript = ai.Body.GetComponentInChildren<CustomScript>();

    Then, in your Execute method, you could just do something like:

    myScript.myVariable = (whatever type is appropriate, int, GameObject, float, even a custom type).

    NOTE: I haven’t got Unity 4 yet nor the updated version of RAIN here where I actually have custom scripts written to test this on. Also, I am still pretty new to C# overall so there may be a more elegant or efficient way I’m just not aware of yet.

    Hope this helps.

    #4761

    prime
    Keymaster

    I posted this answer in another thread, but I believe it is what you are asking here as well:

    To work with variables, use AI WorkingMemory.

    In a custom action, you can get the value of a variable like this:

    float health = AI.WorkingMemory.GetItem<float>("health");

    To set the value of a variable it looks like this:

    AI.WorkingMemory.SetItem<float>("health", health);

    To check if an item has been assigned at all:

    AI.WorkingMemory.ItemExists("health");
    #4762

    prime
    Keymaster

    Also, if you want to make a parameter in your custom action available in the BT Editor, simply make the type of that variable Expression. For example, if your custom action has this:

    Expression strength = new Expression();

    then your custom action node in the behavior tree will show a “Strength” field. You would evaluate strength in your code like this:

    if ((strength != null) && (strength.IsValid))
    {
      float tStrength = strength.Evaluate(AI.WorkingMemory, AI.DeltaTime).GetValue<float>();
    }
    #4763

    Aaron Mueller
    Participant

    I’m not sure how my post is so jacked up. I guess I’ll blame Firefox. *sigh*

    #4766

    Sprakle
    Participant

    Also, if you want to make a parameter in your custom action available in the BT Editor, simply make the type of that variable Expression. For example, if your custom action has this:

    
    Expression strength = new Expression();

    then your custom action node in the behavior tree will show a “Strength” field. You would evaluate strength in your code like this:

    
    if ((strength != null) && (strength.IsValid))
    {
      float tStrength = strength.Evaluate(AI.WorkingMemory, AI.DeltaTime).GetValue<float>();
    }

    That is exactly what I was looking for. Thanks!

    #4797

    NightOwl
    Participant

    I’m probably just terrible at this but its not working out for me. Here is my unity script:

    import RAIN.Core;
    import RAIN.Action;
    var test : float = 0.5;
    function Start () {
    }
    function Update () {
    	AI.BasicMemory.SetItem("lanternlevel") = test;
    }

    Which is giving me the error

    Assets/Scripts/wolfMSG.js(12,31): BCE0049: Expression 'AI.BasicMemory.SetItem('lanternlevel')' cannot be assigned to.
    

    Please let me know if you need more information. Thanks

    • This reply was modified 3 years ago by  NightOwl.
    • This reply was modified 3 years ago by  NightOwl.
    • This reply was modified 3 years ago by  NightOwl.
    • This reply was modified 3 years ago by  NightOwl.
    #4815

    prime
    Keymaster

    @NightOwl - It should look more like this:

    AI.WorkingMemory.SetItem.<float>("lanternlevel", test);
    #4834

    NightOwl
    Participant

    I’m getting this error now:

    
    An object reference is required to access non-static member'RAIN.Core.AI.Body'
    

    Any ideas?

    • This reply was modified 3 years ago by  NightOwl.
    • This reply was modified 3 years ago by  NightOwl.
    • This reply was modified 3 years ago by  NightOwl.
    #4838

    safacon
    Participant

    Your template should look like this.

    
    import RAIN.Core;
    import RAIN.Action;
    @RAINAction
    class ActionTemplate_JS extends RAIN.Action.RAINAction
    {
    	function newclass()
    	{
    		actionName = "ActionTemplate_JS";
    	}
    	function Start(ai:AI):void
    	{
            super.Start(ai);
    	}
    	function Execute(ai:AI):ActionResult
    	{
            return ActionResult.SUCCESS;
    	}
       	function Stop(ai:AI):void
    	{
            super.Stop(ai);
    	}
    }
    

    Then in start, execute, or stop you could reference the AI using ‘ai’.

    
    ai.BasicMemory.SetItem("lanternlevel", test);
    
    #4840

    NightOwl
    Participant

    I currently have this.

    import RAIN.Core;
    import RAIN.Action;
    var test : float = 0.5;
    @RAINAction
    class ActionTemplate_JS extends RAIN.Action.RAINAction
    {
    	function newclass()
    	{
    		actionName = "ActionTemplate_JS";
    	}
    	function Start(ai:AI):void
    	{
            super.Start(ai);
    	}
    	function Execute(ai:AI):ActionResult
    	{
            ai.BasicMemory.SetItem("lanternlevel", "test");
            print (AI.WorkingMemory.GetItem<float>("lanternlevel"));
            return ActionResult.SUCCESS;    
    	}
       	function Stop(ai:AI):void
    	{
            super.Stop(ai);
    	}
    }

    And it still returns

    Assets/NewBe.js(23,19): BCE0020: An instance of type 'RAIN.Core.AI' is required to access non static member 'WorkingMemory'.
    
    • This reply was modified 3 years ago by  NightOwl.
    #4842

    safacon
    Participant

    Line 23 isn’t using the reference

    
    print (AI.WorkingMemory.GetItem<float>("lanternlevel"));
    

    should be:

    
    print (ai.WorkingMemory.GetItem<float>("lanternlevel"));
    
    #4969

    Hank
    Participant

    I’ve inserted the code

    Expression strength = new Expression();`

    into the code template and I receive the error

    Assets/AI/Actions/RandomWalk.cs(13,9): error CS0246: The type or namespace name `Expression’ could not be found. Are you missing a using directive or an assembly reference?

    Pretty new to this, just trying to figure out what I can do…

    • This reply was modified 3 years ago by  prime. Reason: Edited only to fix code drawing issue
    #4978

    prime
    Keymaster

    Expression is in the namespace RAIN.Representation. Make sure you have a using/import statement for that.

    #5293

    justinliebregts
    Participant

    It should be noted that if you want the Expression to show in the CustomAction in the Behaviour Tree Editor, then it needs to be declared as public.

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

You must be logged in to reply to this topic.