Transfering variable between scene tree (not game wide)

Godot Version

godot 4.2

Question

I have an object(an enemy). It’s AI is a finite state machine.
The object(enemy) node tracks and stores targets in an array. It also has a “primary target” variable where it selects, in this case, first item in the array.

The various states are children of the state machine node, which is in turn a child of the object(enemy).

I want a state (follow_target) to get the “primary target” variable from the parent
object(enemy), and use that to follow. But I’m unsure of how to do this.
I could use an autoload resource, but there might be multiple instances of the object(enemy) in once scene , and I want the individual objects to be able to independently track their own arrays of target, not a single global target. But I’m not sure how to communicate the “primary target” variable locally within it’s indvidual tree and only that tree.

Thanks for taking the time to read my question.

can you provide how your node tree looks like for this enemy scene?

1 Like

I don’t exactly know how the enemy AI detects a target, but if it’s with an area 2d or maybe a raycast, they should be able to get the node that it’s colliding with.

So you could (in theory) store the nodes of the targets and use them in a variable when needed.

1 Like

A lot depends on your code and scene structure here. I think you could create a function in follow_target that takes the primary target as an argument and call it from the enemy script, then pass the primary target variable as the argument.

Or a quick and hacky way is to do get_parent() on the follow_target script to get your parent node and access its variables that way, but not recommended if you are going to use the follow_target node anywhere else

1 Like

If I understand correctly, you have a single fsm with a single “blackboard” of data and you want some data to not be shared between FSM “users”.

Then those entities must have that data locally in some way or the blackboard needs to have a dictionary [Object_ID,variable] to support many different entities’ data.

Yes! Will a screenshot suffice?

Yeah, that’s essentially what I have the object(enemy) primary node’s script doing. Fella enters the area2D detection ring, gets logged in a target array, and a variable for “primary” target, which takes the first target index in the array. So I have that variable packaged up and ready to go. And I want a fsm state machine child node script of the object(enemy) node, to be able to call that data from that array.
BUT, I also can’t store it in a global data bus that all instances of that object(enemy) will call from. So I guess what I need is a local resource for that node tree maybe? Are localized resources a thing?

You understand correctly.

Hmmm, I’m interested in your point about having a dictionary that support many different entities data.

Hypothetically, could I also then use that same structure to override individual FSM user’s “local” targeting, and direct them collectively at a specific target with some kind of “master-brain” control node?

I don’t exactly know how your state machine works, but perhaps you could send a custom signal from one node to the other, and then just put in the array as a value for it?

yes, it could have a global and per-entity variables/settings, it depends on how generic the state machine is, also remember that resources are shared so that could be another approach to “shared” variables.

1 Like

You should just have a reference to the parent object in each state using an export. With that, you can get any data you need from the parent object from any state at any time.

I usually use Groups to share info between scenes. I also have a global file in AutoLoad whose only purpose is to store and receive and update global variables. These are the 2 best ways to communicate. You can also use signals to achieve the best performance by avoiding code inside the _process function always waiting for something to happen

I want a state (follow_target) to get the “primary target” variable from the parent
object(enemy), and use that to follow. But I’m unsure of how to do this.

In your follow_target script you can export a variable that is set from the parent script:

# follow_target.gd
@export var target: Node
# enemy.gd
func _on_primary_target_updated() -> void:
    # Assuming you have a reference to these configured already.
    state_follow_target.target = primary_target

In general it’s good practice to signal data up and pass data down. This is an example of the latter.

2 Likes