Instance Index Change

Hello!
I’m having a problem with removing instances. I spawn them through a blueprint and store every instance index in a map so I can ‘reference’ them. But if I remove an instance the whole map gets messed up.
I just found out that’s because if I remove an instance the indexes will change for all the others (or at least for ones with the higher index values).

I read an idea that in the map I should decrease every higher up indexes than the removed one. I find this method quite cumbersome and since I’d possibly have hundreds of instances I’m not sure it’d be good for the performance doing it every time an instance is removed.

I also read someone mentioned “Dynamic Instance Buffer”, but I couldn’t find that anywhere. Is this something that still exists and I just couldn’t find it or did it get removed or renamed or what about it?

So just for clarification, my problem here is that the indexes change at every instance remove and because of this I can’t really keep track of them. Is there any solution to this like a way to prevent the indexes from changing?

1 Like

Have a look at HierarchicalInstancedStaticMeshes - when you remove an instance, it does the equivalent of a TArray.RemoveSwap so the last index gets swapped with the removing index

2 Likes

Hey @Tsybe!

I would suggest replacing your removed instances with an empty, a replacement. Just a placeholder! That way it will keep your array nice and neat, and also not throw null if you try to pull from an index that has been “removed”.

Hey @RecourseDesign!

I tried it with HISM instead of ISM but the problem still occurs. If I remove for example the 6. instance index from the instances then the old 7. becomes the 6. and the old 8. becomes the 7. and so on, and it’ll end up mismatched with my map variable.

And to be honest I don’t know what this should mean and why it would be good for me.

Hi @Mind-Brain, thanks for your suggestions!

So instead of removing the instance you suggest replacing it? It sounds great, but I don’t know how to do it in practice. Unfortunately I can’t find any node like that, could you give me its name please?

It doesn’t move the indexes, it just takes the last instance in your component and changes it’s index to that of the one you just removed - all you need to do is update your Map to reflect that one change.


I’ve read of some people, rather than removing the instance, just setting it’s scale to 0,0,0

Hmm… it’s very interesting, I tried to do a similar thing:

The “Instances” is an actor that spawns at beginplay,- it contains multiple instance components, like the HISM, - after that I spawn 9 instances to the HISM.

If I’m right and based on your images, my event should remove only one instance even if I run it numerous times. But what it actually does, it removes 4 instances of the 9 until the instance count goes under 5.

Any idea? Could this be some setting issue?

Yeah, I also read, some said they moved the instances out of the playable area. These aren’t either that bad solutions, but it’d be great if there is a better one.

*And one more question: what happens when you add another instance after removing those two? What index will it get?

It does still remove them, if you remove the same index number, it removes the last instance:

image

Yeah those were not really good options for me either - but I’m finding that the HISM works very well - and is fast and easy.

Adding another instance will yield the index of (NumInstances-1) as usual.

Yes, it’s great, in performance it’s amazing. It’d be even better if I could keep track of the instances. :smiley:

I don’t really get this, if you remove HISM Instance Index 1 twice. How did “Instance 4” get removed? Shouldn’t it look like the ISM or shouldn’t only “Instance 2” get removed?

When you remove an instance - it doesn’t delete it from the array, it just takes the last instance (NumInstances-1) and moves it into the index you are removing, then just removes the last index in the array.

Some pseudo code is:

RemoveInstance(index) { 
instanceList[index]=instanceList[instanceList.Num()-1];   instanceList.Remove(instanceList.Num()-1);
}

So if you have 4 instances, they will be:

0 - Instance1
1 - Instance2
2 - Instance3
3 - Instance4

If you then remove index 1, that list becomes:

0 - Instance1
1 - Instance4
2 - Instance3

And if you then remove index 1 again, that list becomes:

0 - Instance1
1 - Instance3

2 Likes

Ohh, okay, it makes sense now, thanks! So with HISM it swaps the index with the last and then removes it, but with ISM it removes it without swapping it, isn’t it? And that’s why all the Instances with the higher Index will decrease by one with ISM.
Could I ask you what about the “Remove Instances” node, in both case with HISM and ISM?

Exactly!

Only the HISM has the RemoveInstances in 4.27 which I’m using (5.00 has it in ISM too), and it works in the same way as the RemoveInstance does:


1 Like

Thank you! Even if I didn’t get a direct solution, I found out very useful information about ISM and HISM. I highly appreciate your answers and time!

2 Likes

I don’t really understand the topic entirely, I don’t think, but you’re either using the wrong data structure, or you’re using the right data structure in an incorrect way.

If your code can’t handle a member of the data structure disappearing, then you can’t really expect to use a TArray. I think the problem is more on how you’re accessing the data in the list, than what the list is, though.

The problem isn’t with or about the map variable. It’s about the changing indexes of the instances after one (or more) is removed. But with @RecourseDesign’s help, after understanding what is really happening when an instance is removed, it’s easier to start making a solution to it.

1 Like

ok, so, there is a variable type called a Map, which has stable indices. Arrays do not have stable indices. But I’m realizing here that this looks like we’re not even talking about anything that is actually a map or an array, so I’m not sure my input is helpful at all. Apologies!

Hey @Tsybe! Sorry for the late reply!

So what I was saying was when you remove an item from the index you can use “Insert” directly after your “Remove” to put an invisible, hidden-in-game object with a given class in its place(you would make this yourself), with the “index” pin on the insert being filled with the one you removed. As long as the item added to the array is of the desired class, it can be an instance of something that has very very little data involved but still take the place of the removed item, to preserve the array indices. Like a filler.

I’m not saying it’s the most efficient method, but when you have gone so far in and there’s no looking back, workarounds can help get the game done. :slight_smile:

1 Like

I’m already using a Map variable exactly because of the reason that you mentioned. I also feel like we misunderstand each other. Sorry if my question wasn’t clear enough.

My problem wasn’t with my variable, it was about the indexes of the Instances when one instance gets removed the Instances change indexes. Fortunately, I already discussed it with @RecourseDesign above if you are interested.

Don’t feel sorry, help is always appreciated!

1 Like

Hi @Mind-Brain, thanks for the reply, no worries.

I understand now! But my problem wasn’t with the variable’s indexes, it was with Instances’ indexes. Maybe I just didn’t clear this enough, sorry for that. @RecourseDesign helped me find out what is going on when an instance is removed and what’s the logic behind the index changes. So I’ve already thought of a workaround, but I couldn’t test it yet. I appreciate your answer.

1 Like

@Tsybe No big deal! Sorry for the miscommunication, I thought I understood what was going on. If you get time, you should post your solution here once you figure it out, so others can get a fix if they run into this issue! :slight_smile:

1 Like