How can I dynamically modify the data at the BehaviorTreeReference node through C# code

MirrorDraw

New member
I have a generic behavior tree and reference it in many trees.
  • I want to use different parameters in different trees.
  • I can't use public variables because of hot updates.
  • I need to change it in code, but it doesn't work no matter how much I try, okay.
 

Justin

Administrator
Staff member
You can subclass the BehaviorTreeReference task and override the GetExternalBehaviors method.
 

MirrorDraw

New member
I need to modify the parameters and callbacks of the internal Task of the Behavior Tree Reference, not the Variables of the Behavior Tree Reference.
 

Justin

Administrator
Staff member
What do parameters/callbacks are you trying to modify? If you override GetExternalBehaviors you have complete control over what trees are returned.
 

MirrorDraw

New member
I don't want to change the referenced tree, but the nodes in the referenced tree.
  • For example, the following code is invalid.
exTree_Log.FindTask<Log>().text = "Log Success";

Snipaste_2021-08-03_16-33-32.png
 

MirrorDraw

New member
Earlier I used the following example to modify the node BehaviorTreeReference, but it didn't work.
Running tree does not print "Log Success".

C#:
    private void Test1()
    {
        //Set Log
        var exTreeAsset_Log = Resources.Load<ExternalBehavior>("Log");
        var exTree_Log = GameObject.Instantiate(exTreeAsset_Log);
        exTree_Log.Init();
        exTree_Log.FindTask<Log>().text = "Log Success";

        //Set Test
        var exTreeAsset_Test = Resources.Load<ExternalBehavior>("Test");
        var exTree_Test = GameObject.Instantiate(exTreeAsset_Test);
        exTree_Test.Init();
        exTree_Test.FindTask<BehaviorTreeReference>().externalBehaviors = new ExternalBehavior[] { exTree_Log };

        //Set Tree
        var tree = new GameObject("Test").AddComponent<BehaviorTree>();
        tree.StartWhenEnabled = false;
        tree.ExternalBehavior = exTree_Test;

        //Run
        tree.EnableBehavior();
    }

1.png2.png
 

Justin

Administrator
Staff member
You can overload the variables. In your reference tree you'll want to create a new SharedVariable and then create a new SharedVariable in the main tree with the same name/type. From there the variable will be replaced within the external tree with the main SharedVariable, and you can get/set the variable like any other variable.
 

MirrorDraw

New member
  • You can overload the variables. In your reference tree you'll want to create a new SharedVariable and then create a new SharedVariable in the main tree with the same name/type. From there the variable will be replaced within the external tree with the main SharedVariable, and you can get/set the variable like any other variable.
    • But I set the callback in the node, as shown in the following example.
    • Because of hot updates, I can't write the logic directly inside the node; I have to assign it externally.
1628130950816.png
 

MirrorDraw

New member
I found that after the behavior tree runs, the internal tree reference is converted to multiple nodes, and it is easy to set the parameters within the reference tree through code. However, this is not friendly, and I sincerely hope that in the future we can directly set the nodes in the internal reference tree.
 

MirrorDraw

New member
The plug-in, meanwhile, doesn't seem to have the ability to build trees from code. (Add, modify, remove nodes) hopefully, in the future, the tree will be built on the fly, which will allow more possibilities. For example, a game that can customize its strategy, if it can build a tree from code, will allow users to build the complex strategy they want.
 

MirrorDraw

New member
I found that after the behavior tree runs, the internal tree reference is converted to multiple nodes, and it is easy to set the parameters within the reference tree through code. However, this is not friendly, and I sincerely hope that in the future we can directly set the nodes in the internal reference tree.
C#:
    private void Test1()
    {
        //设定并且空运行一次
        var tree = new GameObject("Test").AddComponent<BehaviorTree>();
        tree.StartWhenEnabled = false;
        tree.ExternalBehavior = Resources.Load<ExternalBehavior>("Test");
        tree.EnableBehavior();

        //设置节点
        tree.FindTask<ConditionGeneric>().isSuccess = ()=> { return true; };
        tree.FindTask<ActionGeneric>().onAction = () => Debug.LogError("设置成功");

        //运行
        tree.EnableBehavior();
    }
 
Top