You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
It's quite frequent to iterate over arrays to find best element. For example, nearest target or weakest target. It's not quite convenient to do everything within one BTTask
Proposed solution
Introduce MinElement decorator, having one child task.
It accepts 3 variables
@export Array var: array to iterate
@export Element var: where to store element from array
@export Metric var: where child task must write a metric to optimize
Internal variables:
var_predicate_task: BTTask=get_child(0)
var_optimized_metric#metric to storevar_element_id: int#current array elementvar_currently_best_element: int#best element
func_tick(delta) ->Status:
vararr=blackboard.get_var(array_var)
if_element_id>=arr.size(): #condition when all elements processed. blackboard.set_var(element_var, arr[_currently_best_element])
returnSUCCESSblackboard.set_var(element_var, arr[_element_id]) #take next elementvarsub_status=_predicate_task.execute(delta) #execute predicateifsub_status==RUNNING:
returnRUNNINGifsub_status==FAILURE: #stubreturnFAILUREvart=blackboard.get_var(metric_var) #get predicate outputif_element_id==0ort<_optimized_metric: #compare metric_optimized_metric=t_currently_best_element=_element_id_element_id+=1returnRUNNING
Alternatives
Could be also MaxElement added, or additional argument introduced to specify whether min or max element must be searched (in this case decorator can be called BestElement)
The text was updated successfully, but these errors were encountered:
The purpose of this decorator is to combine it with a child task to find the "best" element in the array and store it on the blackboard, right? Not sure why it wouldn't be convenient to do this in a single task. It seems to me that this kind of a job would be best represented by something like array_reduce in Python. And Expression can be used to define the reduction logic (user-specified). To find the lowest value, the expression can be as simple as min(a, b).
ArrayReduce task specification:
Apply expression to elements of an array cumulatively, left to right, and store result on the blackboard
In other words, reduces an array to a single value (a sum, a minimum, a maximum, etc.)
Parameters
array_var -- specify blackboard variable that holds an array
expression -- Expression with a and b inputs; task is set as the base instance (so anything that can be used in a task, can also be used in this expression)
initial: BBVariant -- provide starting value for a (optional)
result_var -- variable to store the results of the reduction
To find the closest node in an Array[Node2D], the expression parameter could look like this:
agent.global_position.distance_squared_to(a.global_position)< agent.global_position.distance_squared_to(b.global_position)? a : b
Problem statement
It's quite frequent to iterate over arrays to find best element. For example, nearest target or weakest target. It's not quite convenient to do everything within one BTTask
Proposed solution
Introduce MinElement decorator, having one child task.
It accepts 3 variables
@export Array var
: array to iterate@export Element var
: where to store element from array@export Metric var
: where child task must write a metric to optimizeInternal variables:
When decorator executed:
On tick
Alternatives
Could be also MaxElement added, or additional argument introduced to specify whether min or max element must be searched (in this case decorator can be called BestElement)
The text was updated successfully, but these errors were encountered: