Variables in Actor and/or Blackboard

As I’m developing my AI, I’m running into an issue where I find myself duplicating variables between the AI’s actor and it’s blackboard. For example, my AI has a variable that keeps track of an object (type of actor) relating to its current task. I need to know this in both the actor’s blueprint and also in the behavior tree. So I ended up with a variable in both. The issue is that I have to keep then in sync. If one is changed, I need to change the other. I can see this becoming an issue as the AI grows with more variables and more edge cases.

These are the options I can think of.

  1. Use a Get/Set function on each variable in the blueprint. In the Set function, update the blackboard variable. The only catch with this, is you have to make sure you always use the Set function, and never accidently set the variable directly. There is no way in blueprint to “protect” the variable from this. I also don’t like the idea of ending up with dozens of get/set functions clogging the blueprint.
  2. Abuse OnRepNotify, which would eliminate the Get/Set functions above, and provide the same functionality without worrying about setting the variable directly. This feels dirty though.
  3. Store the variables only in the blackboard and then have the blueprint get/set the blackboard values only. I just don’t know what the overhead involved is with getting blackboard values every time you need them in blueprint. Anyone know? For example, if you need a type of actor, blackboard can only store Object, so you have to get that and cast to your actor in blueprint. The other issue is all the nodes involved and having to get values by key names (yuck).
  4. Store the variables only in the blueprint and have the blackboard get/set these variables directly. This seems like the cleanest approach, however I’m not sure what the overhead is with running a service in the behavior tree that is constantly checking a value of a variable from the actor’s blueprint, instead of just monitoring a blackboard value. If I go this path, then what is the point of the blackboard? I may as well not use it at all.

How do you handle shared variables between the AI actor and its blackboard? Is there another option I’m not thinking of?

Hey @wilberolive!

Don’t worry, this doesn’t matter for overhead because the thing you’re casting to is guaranteed to be loaded in, therefore it’s practically null impact.

You’re forgetting #5: Get a value and set it into the blackboard using “Set BBkey as Float/Int/String/etc” nodes any time something the behavior tree USES is changed. Don’t store “current walking goal vector” on the AI character; that’s something that only the Behavior Tree needs so keep it on the BB. :slight_smile:

This then makes the rest of the Behavior tree able to call on the variables easier, as it is now stored on the BB, and if you store it on the character then you’d have to constantly be checking the character’s variables with a Service node. Right?

Thanks for the reply. I agree that keeping things in the BB that only it needs is fine and I do that already. It’s the stuff I need in multiple places. The BT needs to know, the pawn needs to know, the UI needs to know.

For example, say your agents had some sort of health stat. The BT needs to know what that is to make decisions, the pawn needs to know what it is for some logic and the UI needs to know what it is to display it. So where do you store it? On the pawn? But then the BT has to poll the pawn blueprint with a service. On the BB, but then the blueprint has to do a convoluted get from the BB every time and you lose the ability to just inspect the value on the blueprint in debug… and you have to store the key names in the blueprint anyway to look these values up. Duplicate the variable in both places, but then you have to keep it in sync?

Well, you shouldn’t need a large amount of variables to keep track of for AI decision making purposes. Something like the example here regarding health, I would use a setBBKey because it’s not constantly moving, it’s a value changing when there is an interaction- so 1 frame usage per change. You would want to use a Service for something that can change constantly, such as distance to the player, and that would just be on the BT. (Unless it’s needed on the blueprint)

I think you can use “Make Literal Name” and pass that into the “Set BB Key” node so you don’t have a big list of BB Key variables, keeping your blueprint neater and cutting down on clutter. :slight_smile: