keep in memory a specific sort of a list ?

Hello blender artists,

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.

I do not know why you want to keep this list. It can be invalid at every frame. So you need to recalculate it all the time as you already do.

Wouldn’t it be better to look for the nearest only in situations when you need it?

What are situations you want to find the nearest object?

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 sounds like you’re keeping track of the last closest targets and want to store the list with the object - you could store it as a game property.

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)

Hello and thank you for anwsers,

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 :slight_smile:

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.

Hello, yes monster you understand right.

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).

Thank you again and good blending.