I allow my main character to track its nearest target with the use of the tab key and a track to actuator,
press to enable the track, press to switch the target assigned to the track if it’s enable, hold to disable the track.
To find closest targets I create a list where I append all objects which contain the property ‘enemy@’ and
I sort the list according to the distance between target objects and the main character with the following code:
target_list = []
for obj in scene.objects:
if ('enemy@') in obj: target_list.append (obj)
target_list = sorted (target_list, key = lambda obj: obj.getDistanceTo(main_character))
But my problem here is because the sort is always performed it cause untimely change of the target when the character move,
which I don’t want because I can want to keep the target already in track even if it’s not the nearest anymore.
So I would like to not update the sort when the track is enabled and keep the sort performed before the activation of the track,
I tried this code which only sort the list when the track is not enable :
target_list = []
for obj in scene.objects:
if ('enemy@') in obj: target_list.append (obj)
if targeting > 0: target_list = sorted (target_list, key = lambda obj: obj.getDistanceTo(main_character))
But here the sort don’t stay in memory when the track go to enable, and it come back to the original sort.
So I would like to know if you know a trick to keep in memory a sorted list without constant update ?
I hope I’m clear in my explanation, thank you in advance, and wish you good blending.
You shouldn’t really be sorting such data in realtime, as it incurs a significant performance cost as target counts increase.
As Monster points out, you only need to request the target when you start your targetting.
You shouldn’t really be sorting such data in realtime, as it incurs a significant performance cost as target counts increase.
As Monster points out, you only need to request the target when you start your targetting.
It might also be sensible to use list.sort rather than sorted, because you’re already constructing a list.
target_list = [o for o in scene.objects if "enemy@" in o]
target_list.sort(main_character.getDistanceTo)
Or in your case, only the closest is needed
target_list = [o for o in scene.objects if "enemy@" in o]
target = min(target_list, key=main_character.getDistanceTo)
Maybe it wasn’t clear but I don’t just want to keep one and only one object, but more than one because I allow the switch between more than one nearest object (three right now but can be more, I wouldn’t use a list if I wanted to store just only one object)
so I create and sort the list to use it for the configuration of the tracked target, with a code like this :
target_enum = owner['target'] # switch with tab key for something like 0>1>2>0>1>2>0>etc
target = target_list[(target_enum)] # track the object which has the position in the list provide by the target_enum property
I don’t think that the invalidity of the list is an issue because I can know when an object will no longer exist and so disable the track or update the list before this appen.
I tried to stop the update of the list or stop its sort when the tracking is enable, but it return an empty list or the sort isn’t right and I can’t use it to configure my target.
ps: ok agoose77 I will use list.sort instead of sorted.
Essentially, only set the variable when you switch the tracking target (i.e if pressed_t: own[‘targets’] = calculate_targets(own))
Good luck, nice work
A) If I understand you right, you want at a certain time determine the three nearest objects (in order of the distance)?
B) You want to cycle through this three already determined objects, at any other time ( key press)?
I suggest you implement theses as to separate operations. E.g. search and cycle
A list would be indeed a good way to be part of the data model. You can store a the reference to the list in a property. Both operations can access this property anytime. The search writes the list, while the cycle reads the list.
I wasn’t aware that we can directly store a list in a string property,
so only when I active the tracking I create my target list, sort and store it (search),
and then during the tracking I can use this stored list like my previous one to cycle trough its three first objects or more (cycle).
Now I just need to be careful about the invalidity of the target,
I manage most of this with a distance between the tracked target and my main character,
and some others with a distance between the spawner of the target and my main character,
and if the distance is to high I cancel the tracking (or reactive the tracking to update the list, I will try both).