Download

Instanced Static Mesh, Removing Instance Issue

I guess I didn’t properly describe what my problem was, these brown boxes on the image all belong to 1 ISM component.

Let’s take the image above for example;

  1. I left-click and my bomb BP fire off traces in each direction. It collides with a mesh in all 4 directions, those with Grid ID 164, 146, 124 and 143.
  2. I store these 4 integers in an array.
  3. I loop through this array, and supply Remove Instance with the integer.

What happens here is when I remove for example the instance at index 164, the instance at index 146 will no longer be the same. It sometimes move down to 145, keyword; sometimes.

Sometimes it works, sometimes it does not. And I can’t seem to figure out why that is.

Ahhh, this is an entirely different problem :).

Then let me ask another question. Do you remove the index as well from the array or only the instance?

As far as I know we can’t really access the ISM’s array itself via blueprints, I only use Remove Instance. It works the way I want it, I just can’t seem to figure out why sometimes it will shrink the array like the tooltip says and sometimes not.

Picture of what I’ve tried*(2 methods)*;

Hmmm…

I have the feeling that everytime you do something to the blueprint actor/call something within it, the actor is being updated. And as far as I know, the ISMs/grids are components of your BP_GridGenerator. That means if you remove an entry or even add an existing one, the array will update itself and start from scratch and give the components a new order/new index.

I don’t know, if this would change anything, but what will happen, if you create an array inside your BP_GridGenerator and add every instance/component being run through it? You will get an array populated by the right instances, but it won’t dynamicly change the order, if you update your actor in any way.

Ah, thanks for the clarification! Will check this out later today and return with results :slight_smile:

Edit:

I decided to go with the easier method of comparing their transforms. Since I break the loop once a match is found - the performance is pretty nice, though I haven’t tried it with super large grids yet. I captured a quick little video to showcase the results;
https://youtube.com/watch?v=xGo3feZchQs

Some more testing, then I need to re-create all the interfaces I made for 4.11.2 and hook everything up for multiplayer. Hopefully we can do some multiplayer testing in a few days :rolleyes:

Maybe im a little late to this party, sorry guys.

Yes, removing an instance index from the component effectively makes every instance with a higher index than the one removed to go down one position.

If you have your instances indexed (which i really recommend you to) with a class or struct that holds their data (component index, instance index, transform, etc), you should decrease every instance index that has a higher instance index than the one removed to keep your data on par.

Cheers! I hope you solved it!

If I may chime in, I too had issues removing the correct instances but this relatively simple setup solved it for me:
RemoveInstance.png
Explanation:
The Int Array stores the indexes we wish to remove. Since removing a lower number will make the instances go down one position, we remove them from highest to lowest.
We store the values that Max Of Int Array returns so we don’t have to run that function over and over (well, twice, instead of thrice).
After removing the returned Max Value, we set the *Item *of the Index that the Max Value had to -1 so that it will not be chosen again as the max value.
Also I suggest clearing the Int Array after it’s all completed.

This is a really old thread but I ran into this issue as well. I created a macro based on ste1nar’s solution here:

e1d0d739099e9c16c6e7d9affaa617fb49d1b4ba.png

I thought it would be worth mentioning that the Hierarchical Instanced Static Mesh Component uses RemoveAtSwap() where the regular Instanced Static Mesh Component uses RemoveAt() so you’ll have to handle it differently for that. This actually worked much better for me because I wanted to have a setup where only a limited number of instances were allowed and the oldest ones are removed as newer ones are added (like a limited size queue). RemoveAtSwap is much easier to handle in this case because I can just start a RemoveIndex at 0 and iterate it every time I remove an instance to have RemoveIndex point to the oldest instance. If OldestInstanceIndex >= MaxInstances then I reset it to 0 (where we swapped an instance in a while ago). With the regular Instanced Mesh Component I’d have to keep track of all the active indices and decrement every one greater than the one I was removing to account for the shrinking.

It’s a rare edge case and I didn’t need the Hierarchical Comp features otherwise but it saved me in this case and might be useful to know for someone else. Also I hope future engine versions could have more transparent ways of handling instance removal because the current system makes it really difficult to use if you’re trying to remove instances continually.

removeinstance.png

I actually did solve this eventually, I just enabled “Use Dynamic Instance Buffer” and I didn’t have to fiddle at all.

UseDynamicInstanceBuffer didn’t help in my case, so I solved this differently. Whenever I need to destroy instance with index X, I find the object that uses the mesh instance with the highest index and make that object use instance X instead. I move instance X to the location that the last instance is at and destroy the last instance. This avoids changing all indices above X.

I’ll add a quick tip regarding that - a dirty workaround, but it does the job in most cases, where we don’t want the indices to shift after removing an instance:
Instead of removing the instance, use the UpdateInstanceTransform and set the scale to 0.
Not ideal, it still probably needs to process the instance for all the culling/LOD queries, etc. but at least it practically ‘removes’ it without shifting indices :slight_smile:

You can also add an extra ‘FreeIndices’ int array and add any ‘removed’ index to it. Then, when you add new instances, you can check for free indices and use the UpdateInstanceTransform with desired instance transform, using the free index, instead of adding it normally. This way the pseudo-removed instances will be replaced by new instances.

I think I used a similar approach in the end, but instead of scaling it to 0 - I moved it to some world space coordinates far away from the playable area. I think even if you set the scale to 0, collision will remain - albeit very small, but enough to potentially block a player.

Haven’t used instanced static meshes in a while, but is this still the case? I noticed the dynamic buffer option has been removed, maybe it’s enabled by default now?

Sure, moving it far outside of visible area would be a 100% safe approach.

Hm, I never checked the dynamic buffer option so I’m not sure if that worked/works. I don’t know, maybe these workarounds are not needed anymore, but I’d need to test that. I’ve ‘invented’ the scaling-to-0 workaround in like 4.14 or lower, so maybe it’s not needed in new versions.

Dealman, I didn’t read all this, so maybe you’ve already sussed it. But the easy way to bin items from an array is just loop over it backwards. Then you can throw aways items without having to worry…

The original topic was from 2016. Fairly sure enough as changed where this wouldn’t be an issue in the first place.

It sure enough is not for my foliage addon.

The gist of it all is that a hit result returns the ID of the component instance, which can be used to remove or pull relative data for it.
have yet to test this since i’m developing other aspects and have had no need for it yet, but I believe this would work flawlessly now even with the procedural foliage volumes.

So there is this cool video from epic featuring instanced meshes. https://www.youtube.com/watch?v=bOjYP-c4qhA . It basically says that instead of deleting the x index in the hierachy. it gets replaced by the last index of it and thats going to be removed. so everytime you remove an index of it, the last index will be moved there. thats what ruined the structure. simple fix would be to use a normal instanced mesh (ISM) instead of an hism. that worked for me.

I tried emulating erase and swap, but they still get shuffled unknown way. That issue remains unsolved for me for 13 months. How to restore correct indices after removal from HISM?
**Update: **I tried again. Yes, it’s erase and swap. That feel when you fix 13-month bug.

In case anyone needs it, index restoration is something like this:



int instancesNumber = MeshComponent->GetInstanceCount();
for (auto& x: instances) {
    if (x.instanceIndex == instancesNumber) {
        x.instanceIndex = deletedInstance.instanceIndex;
        break;
    }
}


What about removing instances after a certain number of hit. I’m able to remove instances without any problem but I want the player to have to interact multiple times with the instance before removing it.

Gonna link those 2, seems quite related: