Download

Help with for each loop / logic issue

Hi.

I’m trying to get something to work that is driving me insane.
When i spawn an actor it must be names Marker1. Then Marker2 and so forth.
When i delete one the naming takes a step back. For example if i delete Marker3, the next one that will be created is called Marker3.

However somewhere i didnt design things correctly. Because if i created Marker1,2 and 3 and i delete Marker2, then the next time i create one its called Marker3. So i end up with 2 Marker3’s.

So i tried using Get allactorsofclass, then check the names and if the names are equal just delete everything. But that doesnt work well.
Im trying to find a way to basically do the following.

On clicked -> check if actor exists. If it does not spawn actor and name it Marker one. Then marker2 and so forth.
But If clicked and marker 1 does exist check if marker 2 exist, if it does not create it.

Its hard to explain what im going for… perhaps thats the main problem here. I cannot understand the logic though process behind my objective, and therefor cannot create it.

Well describe exactly what you need (and where you want to use it), there may be very simple solution to it all.

You can handle it in simple array, arrays have exactly this functionality, epic calls them arrays but they really are 2 way lists. Or mutant breed of list, 2 way list and array, depending how you look at it.

To get what you need:

  • make array that remembers references to your objects. So every time you spawn one actor there is blue node that has result, store it in array.
  • after you done adding (or removing) item run for_each_item_in_Aarray on whole array, there is integer index result, construct your text name as “Marker”+index, name all those actors in array.
  • to add or remove do not simply add to array, but insert and delete item at place you want
  • then run reindexing function again

You can also forget whole joy of renaming it, just insert and delete items. Construct actor name out of index, make it as function.

I have done something like this, I couldn’t get ForEach to work right, so it ended up more complicated than it needed to be:
I have an array of ints representing the indices and an array of the spawned actors.

Here is spawning the pawn (Spawns a player at cursor location)

I have this GetNumberForIndex macro which makes sure a unique index is used, so if I have players 1,2,3,4 placed and then delete player 3 in-game, the next player placed will be 3, and then 5 . With a ForEach and a Contains node, I kept getting, 3 and then 4 repeated instead of 5 for example (like what happened to you), so I done it this way with the macro instead:

Basically it just starts at 1 and checks if the array contains that number, if it gets to a number not in the array, it uses that as the next player index. The “ValueToStore”.

And then when you want to delete an actor, I done this. There’s a lot here you won’t need, basically I am removing the selected actor and its associated int from their arrays, and then deleting the actor. Make sure destroy actor is the last step though.

Use more loops. What if you had 200 elements array, or array of unknown size?

I haven’t implemented it yet, but the max amount of players that can be placed is 36, which is all the macro checks for. But I agree, in that, and other cases, a loop would be a lot more sensible.

Hi.

Thank you.
In the controller i detect if i have clicked on a specific area.
If that area is clicked it spawns an actor named marker.

In the actor BP (marker) it has
On event begin play cast to gamemodeBP - Get variable (integer - Number spawned) - set variable(name) It then construct the name out of that.

So it updates the integer to keep track of how many was spawned. On deletion it removed one number.
The design flaw is that if you have created up to 5, then decide to delete number 3, the integer will only subtract 1. So int will then be equal to 4. On creation it will then be back on 5.

I am trying to understand how the array tracker workflow would work.
The reason i need to keep the numbering correct is because later i will call on said actors. Number 1 is point 1, then 2 etc. To draw lines in realtime.

@Mosley
I thought about going that route… but it seems to be counter productive. Even though you only set it up once… it still doesnt look pretty. But if all else fails i guess your route will work. Perhaps we both can discover a new way :slight_smile:

Use array solution I described.

Make array that holds references to all those actors. Or make those spawned actors blueprints, and use foreachactor of class, but this may be risky they may be reordered by some memory cleanup from unreal engine. So better is to store those references in array. Then when you spawn/delete you destroy (or spawn) actor and delete or insert item from array.

This way array will always hold correct state of actors.

To get indexes you need do foreach on updated array and compare if actor is around location you clicked, when its there, you have its name as “marker”+index

.

Thank you Nawrot. I havent gotten it right yet… but my results are starting to look a little better… will keep playing around. Fairly new to arrays. They confuse me.

OK i got it to work like i originally envisioned. Thank you Nawrot.

@Mosel3y
How did you get to remove something from the array but keep the space blank? For example, delete index2, but leave index 2 in place so that next add will go into index 2, then 4.

Thx again guys. Achieved what i needed to.
Basicly in the game you place waypoints and then a line is drawn to show the path from one waypoint to another. And the if you delete a waypoint the line updates accordingly :slight_smile: