How to assign StateTree parameters at runtime

Has anyone found a way to assign / update values to a StateTree parameter?

1 Like

Yeah it get’s complicated. You have to use your evaluator in combination with your actor to pass information back and forth.

So you can’t update the parameter specifically, you use those as default values, pass them into your evaluator and then adjust there.

Hopefully that makes sense.

Does that work, sure, does it make sense? That is another story. The current workflow I have found makes parameters useless. If I am going to have default variables or anything I need to update or set from outside the actor using state tree I have to set up a bunch of variables on the actor. Was hoping this would be more like Blackboard and Behaviour Tree than needing to make an external data housing component or the such.

Can you elaborate? I tried what you described but it’s not working.

The parameter in state tree:
image

The variable in the evaluator:
image

Changing the variable’s value in the evaluator did not update the corresponding state tree parameter.

As far as I know, parameters are “set once, read only” data. If you want runtime parameters, you have to

  1. Make a task, global task or evaluator where the variable will be calculated.
  2. Make your variable in this object.
  3. Make it instance editable (click on the eye), or in C++ make it VisibleAnywhere or EditAnywhere (I believe either should work)
  4. Move it to the Output category. It must be spelled correctly, it won’t work otherwise.
  5. Add the task or evaluator object to the tree. If you did everything correctly, you should see a gray bubble saying OUT and you won’t be able to bind to this variable (since you’ll be writing to it)
  6. Set this variable only from this object.

Other tasks and evaluators can then bind themselves to read from this variable.

This is a poorly documented feature, but I got it to work doing these steps.

2 Likes
// for 5.4
template <typename T>
EPropertyBagResult SetStateTreeReferenceParameter(FStateTreeReference& StateTreeReference, const FName ValueName, const T& Value)
{
	auto& InstancedPropertyBag = StateTreeReference.GetMutableParameters();

	const auto PropertyBagResult = InstancedPropertyBag.SetValueStruct(ValueName, Value);
	ensure(PropertyBagResult == EPropertyBagResult::Success);

	// set overriden flag
	if (auto* Desc = InstancedPropertyBag.FindPropertyDescByName(ValueName))
	{
		StateTreeReference.SetPropertyOverridden(Desc->ID, true);
	}
	
	return PropertyBagResult;
}

This is working but emitting warnings, and I didn’t test it in production.

Is making the variables on the actor itself an option or does it HAVE to be on the state tree?
Because on the context actor its easy peasy to read and write variables. :slight_smile:

1 Like

I need almost exactly this, just with the twist that I need to “write” into the evaluator’s variable, not just “read”.

Is this even possible?

Edit:

For anyone out there interested in the answer of my question:

It’s not possible manipulating the value of a variable of an Evaluator via a StateTree-Task. People I have talked with told me - if it is realy needed - to create global variables e.g in the Player’s ActorBP and to create a reference to that Actor in the “Context”-Section of the StateTree so that the tasks or any other area of StateTree can read/write those values via the vairable in that Actor.

2 Likes

Thank you!

This is the method that I have gone with. It works great because in all of the bindings (ie. enter conditions), you can reference variables from the context actor, all while being able to modify them anywhere necessary. HIGHLY recommend this approach.

Are you on 5.4? Have you tried using FStateTreePropertyRef for your tasks that you want to update the parameters? There are limitations on what can be used with FStateTreePropertyRef and the allowed types can be found in StateTreePropertyRef.h. It would require using C++ as the property refs are not Blueprintable.

-James